第五章 自動化框架規劃及用例管理

      自動化測試的主要任務是迴歸測試,所以不可能一個一個地去執行測試用例。要根據測試的目的來組織測試用例,規劃測試用例的架構。以方便測試用例的執行,測試用例的調試,出錯的時候問題定位以及測試用例的維護等。

5.1 自動化架構規劃

   也許是個人原因吧,我比較喜歡測試數據和測試用例分開的規劃方式。這樣的規劃一是比較明確,二是如果出現了問題,我們定位問題的時候比較方便。三是如果被測對象有任何改動,我們只需要修改測試數據就可以了,不需要修改測試用例。

   兼於以上優點,我們現在討論一下自動化架構的規劃。和Web自動化一樣,我們做如下規劃,在工程中創建以下文件夾:

(1)CommonClass:文件夾下存放所有的公共函數,常用的引用或是通用操作等等。

(2)Source:存放配置文件,圖片資源或是其他靜態資源。

(3)TestCases:存放具體的測試用例文件,一個測試用例文件最好是針對一個接口的所有測試用例,如果用例比較多可以分成多個測試文件。

(4)TestData:和測試用例文件相匹配的測試數據文件,以xml文件存方數據,數據的組織形式以測試用例爲單位對應該xml文件中的一個節點。

(5)TestSuites:根據不同的測試需要,把測試用例組織成不同的測試套件,然後在相應的環境中配置執行。

經過這樣的規劃,我們再寫自動化測試用例的時候,在相應的文件夾下添加對應的內容即可。

5.2 CommonClass文件夾內容講解

CommonClass中存放的是我們的公共函數,根據我們的接口自動化測試的需要,我們要創建以下幾個文件:

(1)CurlOperation.php 此文件的主要功能是實現對接口的調用,根據傳遞過來的參數,執行不同的代碼。代碼如下:

<?php

/**

 * 具體的接口調用操作

 *

 * @author SXF

 */

class CurlOperation {    

    public static functionFetch($url, $get_params, $post_params=null) {

        $str = '';       

        if(isset($get_params) && !empty($get_params)) {

            $arr =array();

            foreach ($get_paramsas $key => $value) {

               array_push($arr, $key . '=' . urlencode($value));

            }

            $str =implode("&", $arr);

        }

        if (strpos($url,"?") !== FALSE) {

            $url = $url .'&' . $str;

        } else {

            $url = $url .'?' . $str;

        }

        $ch = curl_init();

        curl_setopt($ch,CURLOPT_URL, $url);

        curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch,CURLOPT_HEADER, 0);

        curl_setopt($ch,CURLOPT_HTTPHEADER, array(

           "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US;rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)",

           "Accept-Language:en-us,en;q=0.5","DIVERSION-VERSION:1","SESSION-TOKEN:".TextOperation::readtoken()#封裝頭內容,讀取Session實現登錄狀態

        ));       

        if(isset($post_params)) {

            // Post method

           curl_setopt($ch, CURLOPT_POST, 1);

           curl_setopt($ch, CURLOPT_POSTFIELDS, $post_params);

            //下面兩行是爲了https請求添加

           curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

           curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        }

        $output =curl_exec($ch);

        curl_close($ch);

        return $output;

 

    }

}

PHP常用的調用Post和Get接口的方法,爲了實現一些兒接口調用需要登錄,我們添加對HTTP頭的封裝,把Session的內容傳遞過來。

(2)DataOperations.php 存放相關的數據操作,我們在此處的主要作用就是讀取測試數據文件Xml,爲測試用例提供測試數據。代碼詳情如下:

<?php

/**

 * 此類爲數據操作類

 * @author SXF

 * @date:2015-3-18

 */

classDataOperations {    

    var $doc;

    public function __construct($filename) {

       $this->doc=new DOMDocument();

      $this->doc->load("TestData/".$filename);

      }

    public functionreadnodevalue($node1,$node2){              

       /*讀取Xml節點的值

        * @param node1:數據根節點

        * @param node2:數據節點

        */

       foreach($this->doc->getElementsByTagName($node1) as $item)

        {

              $list =$item->getElementsByTagName( $node2 ); 

                foreach ( $list as $list1 ) 

               { 

                    $value =$list1->nodeValue;

                    break;

                }           

        }

        return $value;        

    }

    

}

(3)ReadConfig.php 讀取Source下的配置文件config.xml,用於切換host,實現測試用例在不同的環境下運行。具體代碼如下:

<?php

/**

 * 讀取配置文件中的數據

  *@author SXF

 */

class ReadConfig {    

   var $doc;

   public function __construct() {

      $this->doc=new DOMDocument();

      $this->doc->load("Source/Config.xml");

   }    

   public function gethost($type)

    {

       //讀取配置文件中的Host信息

       foreach($this->doc->getElementsByTagName("host") as$item)

       {

              $list =$item->getElementsByTagName( $type ); 

                foreach ( $list as $list1 ) 

               { 

                    $value =$list1->nodeValue;

                    break;                   

               }

       }           

         return $value;        

    }

}

(4)TextOperation.php Text文件的讀寫函數,用於存放登錄接口返回的Token的值到Source/token.txt中,當其他的接口需要登錄狀態的時候,將Token讀取出來,封裝到Http頭中。當然也可以類似於log一樣,把錯誤的內容寫到Source/result.txt文件中,具體代碼如下:

<?php

/**

 * Text文件相關操作

 * @author lys

 */

classTextOperation {    

     public function writetxt($message){

       $open=fopen("Source/result.txt","a+");

       fwrite($open,$message."\r\n");

        fclose($open);

    }

    public function writetoken($message){

       $open=fopen("Source/token.txt","w+");

       fwrite($open,$message."\r\n");

        fclose($open);

    }

    public function readtoken(){

       $open=fopen("Source/token.txt","r");

        $token=fread($open,32);

        fclose($open);

        return $token;

    }

}

(5)Require.php 爲了簡化代碼,我們將需要引用的文件全放到這個文件中,其他的測試用例文件再需要引用的時候,直接引用這個文件即可。具體代碼如下:

<?php
/* 

 *所有需要引用的文件

 */

require_once("CurlOperation.php");

require_once("DataOperations.php");

require_once("ReadConfig.php");

require_once("TextOperation.php");


5.3 Source文件夾內容講解

   Source文件夾中存放的是配置文件,所要用到的圖片文件資源等,目前我的Source文件夾下有如下文件:

(1)img文件夾:存放的是測試用例要用到的圖片文件,裏面有十張圖片,以方便每次上傳的時候實現隨機調用。

(2)Config.xml配置文件。這是配置的是各個測試環境的調用host,這樣我們可以通過修改不同的參數來切換環境。文件內容如下:

<?xml version="1.0"encoding="UTF-8"?>

<!--

這裏是接口測試用到的相關配置

-->

<Setting>

   <host>

       <online>http://api.zhongchou.cn</online>

       <host212>http://*.*.*.*</host212>

       <host170>http://app-4-0.api.zhongchou.cn</host170>

   </host>

</Setting>

(3)result.txttoken.txt。這兩個文本文件用來存放測試用例執行過程中的一些兒內容。Result.txt文件裏存放的是測試用例執行失敗的信息,token.txt文件中存放的是登錄接口返回的token信息,用於其他的需要登錄的接口,將Token封裝到Http頭中實現登錄狀態下調用接口。

5.4 TestCases文件夾內容

這個文件夾下存放的是具體的測試用例文件,每個測試用例文件是對一個接口的所有測試用例。當然測試用例文件也有一定的命名規則:一般是以接口名來頭,以Test結尾。如:LoginTest.php.

下面我們以一個實例講解一下公用函數的使用:以登錄接口http://api.zhongchou.cn/user/login爲例

對應的測試用例文件代碼如下:

<?php

 

/* 

 *登錄接口http://api.zhongchou.cn/user/login測試用例

 */

require_once 'CommonClass/Require.php';

 

class login_Test extends PHPUnit_Framework_TestCase{

   public function testlogin()

   {

       /**

        * 登錄接口檢測

        */

       $rc=new ReadConfig();

       $dr=new DataOperations("LoginTest.xml");

       $url=$rc->gethost("host170") ."/user/login";//讀取配置文件,選擇運行環境

        echo $url;

       $get_params=NULL;

       $post_params=array('identity'=>$dr->readnodevalue("login","username"),'password'=>$dr->readnodevalue("login","password"));

       $content=CurlOperation::Fetch($url, $get_params,$post_params);

       $data= json_decode($content,true);

       print_r($data);        

       if($data['errno']==0)

         {

              $this->assertEquals($dr->readnodevalue("login","serrno"),$data["errno"]);

              TextOperation::writetoken($data['data']['token']);

              print('接口28:登錄成功------------------OK'.'\n');

         }

        else

        {

            print("接口28:登錄失敗---------------Failure!"."\n".$content."\n");

            TextOperation::writetxt("接口28:登錄失敗------Failure!"."\n".$content."\n");

            $this->assertEquals($dr->readnodevalue("login","serrno"),$data["errno"]);

       }

   }

代碼講解:

首先引用我們的公用引用文件Require.php文件,將要引用的公用文件全包含進來。然後創建測試用例函數testlogin(),測試用例文件必須以test開頭,否則phpunit不識別。在函數中初始化配置文件類$rc,數據操作類$dr,並且拼接出URL

由於login接口是Post方式的,從對應的loginTest.xml數據文件中讀取出“identity”和“password”參數對應的值。然後調用公共函數CurlOperation::Fetch()實現調用接口的操作,並將接口返回值json_decode(),然後判斷返回值的errno是否與預期的一樣(從數據文件中讀取的預期值$dr->readnodevalue("login","serrno"))。

5.5 TestData文件夾內容

這個文件夾下存放的是對應測試用例的測試數據文件,一個接口對應一個數據文件,而一個測試用例對應一個數據節點。如login接口的測試用例文件是loginTest.php,對應的測試數據文件是loginTest.xml.其內容如下: 

<?xmlversion="1.0" encoding="UTF-8"?>

<!--登錄接口測試數據-->

<TestData>

    <login name="登錄接口,正常登錄">

      <username>[email protected]</username>

       <password>a000000</password>

       <serrno>0</serrno>

    </login>

    <loginuer name="登錄接口,用戶名錯誤">

        …….

    </loginuer>

</TestData>

這個數據文件中對應兩個測試用例,一個是login正常登錄的測試數據,另一個是loginuer用戶名錯誤的情況,當然這個測試用例數據省略了。以後我們要添加測試用例的時候,只需要在對應的測試數據文件中添加節點和相應的測試數據,在測試用例文件中添加對應的函數即可。

5.6 TestSuites文件夾的內容

   TestSuites就是對測試用例的組織,因爲PHPUNIT是利用PHPUnit_Framework_TestSuite來組織測試用例的,我們只需要創建一個類繼承這個類,然後把相應的測試用例文件添加進來即可。

   如我們創建OnlineRegression.php文件,內容如下:

<?php

/**

 * Created by PhpStorm.

 * User: sxf

 * Date: 15-4-7

 * Time: 下午5:27

 */

require_once'CommonClass/Require.php';

classOnlineResTestSuite extends PHPUnit_Framework_TestSuite {

    public function __construct(){

       $this->addTestFile('TestCases/LoginTest.php');

        /*此處添加所有的測試用例文件

        */

    }

    public static function suite() {

        return new self();

    }

  }

     我們將所有需要執行的測試用例文件,使用$this->addTestFile()函數添加到這個Suite中,然後右擊這個文件,選擇“Run ‘OnlineResTestSuite’”即可執行所有的測試用例。

當然可以根據運行環境啊,測試目的等不同來創建不同的suite文件的。例如,線上迴歸測試環境一般不能產生測試數據,所以有些兒post接口就不能在線上迴歸,此時線上迴歸的suite文件中就不能包含這樣的接口。

5.7 本章小結

   本章我們講解了測試用例的架構規劃,測試用例的組織。當然你可以自己規劃一個喜歡的架構,只要方便執行,調試,出錯的時候的定位準確就可以了。我自己喜歡現在的架構,經過我的實際工作中的實踐,還是相當不錯的。通過本章的學習,你可以把自己編寫的單獨的測試用例組織到一起,根據需要設計出合適的suite文件。下章我們將把這些測試用例集成到Jenkins中,實現無人值守的自動化運行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章