pyhont+unittest的测试固件
在执行一条自动化测试用例时需要做一些测试前的准备工作和测试后的清理工作,如:创建数据库链接、启动服务进程、打开文件、打开浏览器、测试环境的清理、关闭数据链接、关闭文件等。如果每执行一条用例都需要编写上面的代码就会造成代码的冗余,unittest包括一个特殊的hook,用来配置和清理测试所需的所有固件,可以将这些动作放在测试固件(test fixture)里。常用的测试固件方法有4个:
setUp()每个测试方法运行前执行。
tearDown()每个测试方法运行结束后运行。
setUpClass()所有的方法运行之前运行一次,整个测试类运行过程中只运行一次。
tearDownClass所有的测试方法结束之后运行以西,整个测试类运行过程中只运行一次。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 from appium import webdriver
2 from time import sleep
3 import unittest
4 from selenium.webdriver.support.expected_conditions import NoSuchElementException
5 from day05.email_location import EmailLocation
6
7 desired_capabilities = dict()
8 desired_capabilities["platformName"] = "Android"
9 desired_capabilities["platformVersion"] = "8.0"
10 desired_capabilities["deviceName"] = "android Emulator"
11 desired_capabilities["appPackage"] = "com.android.email"
12 desired_capabilities["appActivity"] = ".activity.setup.AccountSetupFinal"
13 desired_capabilities["newCommandTimeout"] = 200
14
15
16 class EmailTest(unittest.TestCase):
17
18 def setUp(self) -> None:
19 self.driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_capabilities)
20 self.driver.implicitly_wait(20)
21 self.lct = EmailLocation()
22
23 def tearDown(self) -> None:
24 self.driver.quit()
25
26 def data(self):
27 self.data1 = {"email": "zhaodongfeng@163.com"}
28
29 def test_case01(self):
30 try:
31 email = self.driver.find_element(*self.lct.email1)
32 self.data()
33 email.send_keys(self.data1["email"])
34 sleep(1)
35 next1 = self.driver.find_element(*self.lct.next)
36 next1.click()
37 sleep(3)
38 up = self.driver.find_element(*self.lct.up)
39 up.click()
40 sleep(1)
41 manual_setup = self.driver.find_element(*self.lct.manual_setup)
42 manual_setup.click()
43 sleep(2)
44
45 except NoSuchElementException as e1:
46 print("没有找到元素", e1)
47
48 finally:
49 print("用例执行完毕")
50
51
52 if __name__ == '__main__':
53 unittest.main()
setUp()方法时在众多测试方法的每个测试方法执行前先被调用执行的方法,而且每执行完一个测试方法都要从setUp方法调用开始后再执行下一个测试方法,有几个测试方法就调用它几次,与代码位置无关,放在哪里都是它先被调用。
tearDown()方法是在众多方法执行完毕后它才被执行,不管这个类里面有多少测试方法,它是在每执行完一个测试方法后被执行的,与书写位置无关,放在哪里都行;无论测试方法是否执行成功都执行tearDown()方法,如果setUp()方法执行失败,则认为这个测试项目失败,
不会执行测试方法也不执行tearDown()方法。执行过程如下:
setUp --> testcase_1 -->tearDown() -->setUp() --> testcase_2 --> tearDown()
因为每执行一个测试方法都会运行setUp()和tearDown(),所以运行效率较低。可以使用setUpClass()和tearDownClass()方法,实现如下过程。
setUp --> testcase_1 --> testcase_2 --> tearDown()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class CircleOperation(unittest.TestCase):
2
3 @classmethod
4 def setUpClass(cls) -> None:
5 # 启动APP
6 cls.driver = StartApp().start_wtx_oppo()
7 cls.driver.implicitly_wait(6)
8 # 登录app
9 LoginApp(cls.driver).login()
10 cls.circle_homepage_lct = CircleHomepageLocation()
11 cls.post_invitation = EditInvitationLocation()
12
13 @classmethod
14 def tearDownClass(cls) -> None:
15 # 关闭APP
16 cls.driver.quit()
17
18 def test_case1(self):
19 pass
20
21 def test_case2(self):
22 pass
setUpClass()必须使用@classmethod装饰器,所有测试方法运行前运行一次,整个测试类运行过程中只运行一次。
tearDownClass()必须使用@classmethod装饰器,所有测试方法运行完后运行一次,整个测试类运行过程中执行一次。
setUpClass()和tearDownClass()方法会增加运行效率,但是用例之间的耦合度高,case与case之间必须有上下级关系,一旦某一条case执行失败,那么所有的case都会执行失败。
在appium里的setUp或setUpClass一般包含启动app的步骤和其他初期数据和环境准备的步骤。tearDown和tearDownClass一般包含关闭App的步骤和其他数据清理和环境清理的步骤。