­

測試開發進階(三十三)

  • 2019 年 11 月 5 日
  • 筆記

局部變量

name: 登錄接口  variables:      username: ${ENV(USERNAME)}      password: ${ENV(PASSWORD)}  request:      url: http://127.0.0.1:8000/user/login/      method: POST      headers:          Content-Type: "application/json"      json:          username: $username          password: $password  validate:      - eq: ["status_code", 200]  extract:      - uname: content.username

可以修改 variables定義變量,導入環境變量作為值

request中可以使用 $變量名來獲取 variables區域下的變量

調用函數

可以調用 debugtalk.py中的函數

例如在該文件中添加

def get_user_agent():      user_agents = ['Mozilla/5.0 AAA', 'Mozilla/5.0 BBB', 'Mozilla/5.0 CCC']      return random.choice(user_agents)
name: 登錄接口  variables:      username: ${ENV(USERNAME)}      password: ${ENV(PASSWORD)}  request:      url: http://127.0.0.1:8000/user/login/      method: POST      headers:          Content-Type: "application/json"          User-Agent: ${get_user_agent()}      json:          username: $username          password: $password  validate:      - eq: ["status_code", 200]

使用 ${get_user_agent()}

這樣就可以動態的使用 User-Agent

校驗

可以用的響應屬性:

  • available
  • response
  • status_code
  • cookies
  • elapsed
  • headers
  • content
  • text
  • json
  • encoding
  • ok
  • reason
  • url
- eq: ["headers.Content-Type", "application/json"]
- {check: "headers.Content-Type",comparator: "eq",expect: "application/json"}

上面兩種寫法效果一致

  • check:指定斷言哪一個字段(實際值)

python3.7/site-packages/httprunner/built_in.py

  • comparator:指定斷言的規則
  • eq 等於
  • lt小於
  • lte
  • gt大於
  • gte
  • str_eq
  • len_eq長度等於
  • len_gt
  • contains 包含
"""  built-in comparators  """  def equals(check_value, expect_value):      assert check_value == expect_value    def less_than(check_value, expect_value):      assert check_value < expect_value    def less_than_or_equals(check_value, expect_value):      assert check_value <= expect_value    def greater_than(check_value, expect_value):      assert check_value > expect_value    def greater_than_or_equals(check_value, expect_value):      assert check_value >= expect_value    def not_equals(check_value, expect_value):      assert check_value != expect_value    def string_equals(check_value, expect_value):      assert builtin_str(check_value) == builtin_str(expect_value)    def length_equals(check_value, expect_value):      assert isinstance(expect_value, integer_types)      assert len(check_value) == expect_value    def length_greater_than(check_value, expect_value):      assert isinstance(expect_value, integer_types)      assert len(check_value) > expect_value    def length_greater_than_or_equals(check_value, expect_value):      assert isinstance(expect_value, integer_types)      assert len(check_value) >= expect_value    def length_less_than(check_value, expect_value):      assert isinstance(expect_value, integer_types)      assert len(check_value) < expect_value    def length_less_than_or_equals(check_value, expect_value):      assert isinstance(expect_value, integer_types)      assert len(check_value) <= expect_value    def contains(check_value, expect_value):      assert isinstance(check_value, (list, tuple, dict, basestring))      assert expect_value in check_value    def contained_by(check_value, expect_value):      assert isinstance(expect_value, (list, tuple, dict, basestring))      assert check_value in expect_value    def type_match(check_value, expect_value):      def get_type(name):          if isinstance(name, type):              return name          elif isinstance(name, basestring):              try:                  return __builtins__[name]              except KeyError:                  raise ValueError(name)          else:              raise ValueError(name)        assert isinstance(check_value, get_type(expect_value))    def regex_match(check_value, expect_value):      assert isinstance(expect_value, basestring)      assert isinstance(check_value, basestring)      assert re.match(expect_value, check_value)    def startswith(check_value, expect_value):      assert builtin_str(check_value).startswith(builtin_str(expect_value))    def endswith(check_value, expect_value):      assert builtin_str(check_value).endswith(builtin_str(expect_value))
  • expect預期結果

數據驅動

testcases/login.yml

config:      name: "登錄接口測試"      variables:          device_sn: "ABC"          username: ${ENV(USERNAME)}          password: ${ENV(PASSWORD)}      base_url: "http://127.0.0.1:8000"    teststeps:  -      name: 登錄      api: api/login.yml      validate:          - eq: ["status_code", 200]

繼承 api/login.yml會與本區域定義的 validate合併覆蓋

一般api路徑下的斷言只進行基礎類型的斷言例如 status_code

testcases會進行其他的斷言

方式一:使用yaml

testsuites/api_testsuite.yml

config:      name: 接口測試套件      base_url: "http://127.0.0.1:8000"    testcases:  -      name: 登錄接口      testcase: testcases/login.yml      parameters:          # 方式一          # 多個具有關聯性的參數,需要將其定義在一起,並且採用短橫線進行連接          - title-username-password-status_code-contain_msg:                - ["正常登錄", "zhongxin", "123456", 200, "token"]                - ["密碼錯誤", "zhongxin", "1234567", 400, "non_field_errors"]                - ["賬號錯誤", "zhongxin11", "123456", 400, "non_field_errors"]                - ["用戶名為空", "", "123456", 400, "username"]                - ["密碼為空", "zhongxin", "", 400, "password"]

運行

$ hrun testsuites/api_testsuite.yml

查看報告

方式二:讀取文件

新建一個csv文件

title,username,password,status_code,contain_msg  正常登錄, zhongxin, 123456, 200, token  密碼錯誤, zhongxin, 1234567, 400, non_field_errors  賬號錯誤, zhongxin11, 123456, 400, non_field_errors  用戶名為空, , 123456, 400, username  密碼為空, zhongxin, , 400, password
- title-username-password-status_code-contain_msg: ${P(datas/accounts.csv)}

方式三:使用函數

debugtalk.py添加

def get_accounts():      accounts = [          {"title": "正常登錄", "username": "zhongxin", "password": "123456", "status_code": 200, "contain_msg": "token"},          {"title": "密碼錯誤", "username": "zhongxin", "password": "1234567", "status_code": 400, "contain_msg": "non_field_errors"},      ]      return accounts
- title-username-password-status_code-contain_msg: ${get_accounts()}

使用py文件調用httprunner

from httprunner.api import HttpRunner    # 創建HttpRunner對象  # failfast:False 用例執行失敗後不終止  runner = HttpRunner(failfast=False)  # 運行用例  # run方法支持如下參數  # yaml用例文件的路徑  # 字典(用例的信息)  runner.run('/Users/zhongxin/Desktop/httprunner_learn/testcases/login.yml')  print(runner.summary)