自動化框架的兩種斷言設計(pytest 版)


自動化測試斷言失敗時,根據不同業務場景,可能需要立即終止或繼續執行。這里以 Appium + pytest 為例。

 

一. 斷言失敗立即終止

 

用途一:用例的預期結果是其他用例的前提條件時,assert 失敗需要立即終止,這是我們設計自動化測試用例時最常見的場景。

用途二:用例中的任何一個步驟執行失敗時,立即終止,因為步驟都執行失敗了,沒有繼續執行下一步的必要。方案:思路與用途一類似,這里把每個測試步驟當做都有一個預期結果(True),封裝每一個具體步驟,步驟結果返回布爾值。對該結果進行 assert,False時立即終止。

 1 def click(self, step):
 2     method_name = sys._getframe().f_code.co_name
 3     try:
 4         element = self.find_element(**step['element_loc'])
 5         if step.has_key('times'):
 6             for i in range(step['times']):
 7                 element.click()
 8         else:
 9             element.click()
10         return True
11     except:
12         print u'%s失敗' % method_name
13         return False
1 for step in self.case_steps:
2     assert self.operate(step), 'error in step: %s' % step

 

 

二. 斷言失敗繼續執行

 

 

主要使用了兩個函數 expect, assert_expectations 。

Demo: test_delayed_assert.py

 1 from delayed_assert import expect, assert_expectations
 2  
 3 def test_should_pass():
 4     expect(1 == 1, 'one is one')
 5     assert_expectations()
 6  
 7 def test_should_fail():
 8     expect(1 == 2)
 9     x = 1
10     y = 2
11     expect(x == y, 'x:%s y:%s' % (x,y))
12     expect(1 == 1)
13     assert_expectations()

Module: delayedAssert.py

 1 '''
 2 Implements one form of delayed assertions.
 3 
 4 Interface is 2 functions:
 5 
 6   expect(expr, msg=None)  
 7   : Evaluate 'expr' as a boolean, and keeps track of failures
 8 
 9   assert_expectations()        
10   : raises an assert if an expect() calls failed  
11 
12 Usage Example:
13 
14     from expectations import expect, assert_expectations
15 
16     def test_should_pass():
17         expect(1 == 1, 'one is one')
18         assert_expectations()
19 
20     def test_should_fail():
21         expect(1 == 2, 'one is two')
22         expect(1 == 3, 'one is three')
23         assert_expectations() 
24 '''
25 
26 # ---------------------------------------------------
27 
28 def expect(expr, msg=None):
29     'keeps track of failed expectations'
30     if not expr:
31         _log_failure(msg)
32 
33 def assert_expectations():
34     'raise an assert if there are any failed expectations'
35     if _failed_expectations:
36         assert False, _report_failures()
37 
38 # ---------------------------------------------------
39 
40 import inspect
41 import os.path
42 
43 _failed_expectations = []
44 
45 def _log_failure(msg=None):
46     (filename, line, funcname, contextlist) =  inspect.stack()[2][1:5]
47     filename = os.path.basename(filename)
48     context = contextlist[0]
49     _failed_expectations.append('file "%s", line %s, in %s()%s\n%s' % 
50         (filename, line, funcname, (('\n%s' % msg) if msg else ''), context))
51 
52 def _report_failures():
53     global _failed_expectations
54     if _failed_expectations:
55         (filename, line, funcname) =  inspect.stack()[2][1:4]
56         report = [
57             '\n\nassert_expectations() called from',
58             '"%s" line %s, in %s()\n' % (os.path.basename(filename), line, funcname),
59             'Failed Expectations:%s\n' % len(_failed_expectations)]
60         for i,failure in enumerate(_failed_expectations, start=1):
61             report.append('%d: %s' % (i, failure))
62         _failed_expectations = []
63     return ('\n'.join(report))
64 
65 # ---------------------------------------------------
66 # _log_failure() notes
67 #
68 # stack() returns a list of frame records
69 #   0 is the _log_failure() function
70 #   1 is the expect() function 
71 #   2 is the function that called expect(), that's what we want
72 #
73 # a frame record is a tuple like this:
74 #   (frame, filename, line, funcname, contextlist, index)
75 # we're mainly interested in the middle 4, 
76 # ---------------------------------------------------

 

 

參考:Delayed assert / multiple failures per test


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM