Skip to content

Commit bc2ca56

Browse files
committed
自动化测试脚本以及自动化测试框架unittest
1 parent 5cd49a0 commit bc2ca56

File tree

8 files changed

+654
-19
lines changed

8 files changed

+654
-19
lines changed

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

Lines changed: 282 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 250 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# AutomatedTestingDemo
22
自动化测试框架测试Demo
33

4-
## Android APP 自动化测试框架
4+
### Android APP 自动化测试
55

6-
### 自动化测试环境安装
6+
#### 自动化测试环境安装
77

88
- Node.js - [下载地址]( https://nodejs.org/en/download/)
99

@@ -21,3 +21,251 @@
2121

2222
> 软件安装以及环境配置可以参考这篇文章:[参考文章](https://blog.csdn.net/zh175578809/article/details/76780054)
2323
24+
#### 编写自动化测试Demo
25+
26+
下面的demo是对系统自带的计算器APP进行测试的,界面元素的id和包名都是通过UIAutomator获取的。
27+
28+
```python
29+
from appium import webdriver
30+
31+
desired_caps = {}
32+
desired_caps['platformName'] = 'Android'
33+
desired_caps['platformVersion'] = '9.0'
34+
desired_caps['deviceName'] = '192.168.115.101:5555'
35+
desired_caps['appPackage'] = 'com.android.calculator2'
36+
desired_caps['appActivity'] = '.Calculator'
37+
desired_caps["unicodeKeyboard"] = "True"
38+
desired_caps["resetKeyboard"] = "True"
39+
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
40+
41+
driver.find_element_by_id("digit_1").click()
42+
driver.find_element_by_id("digit_3").click()
43+
driver.find_element_by_id("digit_5").click()
44+
driver.find_element_by_id("op_add").click()
45+
driver.find_element_by_id("digit_8").click()
46+
driver.find_element_by_id("digit_9").click()
47+
driver.find_element_by_id("op_mul").click()
48+
driver.find_element_by_id("digit_3").click()
49+
driver.find_element_by_id("digit_9").click()
50+
driver.find_element_by_id("digit_2").click()
51+
driver.find_element_by_id("eq").click()
52+
53+
result = driver.find_element_by_id("result").text
54+
55+
if result == "30,352":
56+
print "pass"
57+
else:
58+
print "fail"
59+
60+
# 一定记得退出driver,不然下次运行会直接报错,除非在Appium中手动停止连接
61+
driver.quit()
62+
```
63+
64+
先运行Appium,点击android图标进行设置,主要设置platformVersion,我是用的Appium版本为appium1.4.16,由于appium1.4.16版本最高只支持安卓6.0版本,所以可以[参考这篇文章](https://www.jianshu.com/p/0136e26eee36)进行一些修改设置,然后运行Appium启动连接,再运行上面的demo,可以得到下面的输出结果:
65+
66+
```
67+
E:\Python27\python.exe F:/code/AutomatedTestingDemo/test_demo/test_demo.py
68+
35,023
69+
70+
Process finished with exit code 0
71+
```
72+
73+
### Android APP 自动化测试框架
74+
75+
#### Unittest框架
76+
77+
> 使用unittest编写用例,必须遵守以下规则:
78+
>
79+
> 1、测试文件必须先import unittest;
80+
>
81+
> 2、测试类必须继承unittest.TestCase;
82+
>
83+
> 3、测试方法必须以“test_”开头;
84+
>
85+
> 4、测试类必须要有unittest.main()方法。
86+
87+
##### Test Fixture
88+
89+
> A test fixture represents the preparation needed to perform one or more tests, and any assoicate cleanup actions.
90+
91+
- setUp() : 进行测试前的初始化工作。
92+
- testCase() : 进行测试工作,可以有很多个
93+
- tearDown() : 执行测试后的清除工作。
94+
95+
使用unittest改写上面的自动化测试脚本
96+
97+
```python
98+
import unittest
99+
from appium import webdriver
100+
101+
102+
class MyTestCase(unittest.TestCase):
103+
104+
def setUp(self):
105+
desired_caps = {}
106+
desired_caps['platformName'] = 'Android'
107+
desired_caps['platformVersion'] = '9.0'
108+
desired_caps['deviceName'] = '192.168.115.101:5555'
109+
desired_caps['appPackage'] = 'com.android.calculator2'
110+
desired_caps['appActivity'] = '.Calculator'
111+
desired_caps["unicodeKeyboard"] = "True"
112+
desired_caps["resetKeyboard"] = "True"
113+
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
114+
115+
def test_something(self):
116+
self.driver.find_element_by_id("digit_1").click()
117+
self.driver.find_element_by_id("digit_3").click()
118+
self.driver.find_element_by_id("digit_5").click()
119+
self.driver.find_element_by_id("op_add").click()
120+
self.driver.find_element_by_id("digit_8").click()
121+
self.driver.find_element_by_id("digit_9").click()
122+
self.driver.find_element_by_id("op_mul").click()
123+
self.driver.find_element_by_id("digit_3").click()
124+
self.driver.find_element_by_id("digit_9").click()
125+
self.driver.find_element_by_id("digit_2").click()
126+
self.driver.find_element_by_id("eq").click()
127+
128+
result = self.driver.find_element_by_id("result").text
129+
self.assertEqual(result, "35,023")
130+
131+
def tearDown(self):
132+
# 一定记得退出driver,不然下次运行会直接报错,除非在Appium中手动停止连接
133+
self.driver.quit()
134+
135+
136+
if __name__ == '__main__':
137+
unittest.main()
138+
```
139+
140+
运行结果:
141+
142+
```
143+
Testing started at 11:56 ...
144+
E:\Python27\python.exe "E:\Program Files\JetBrains\PyCharm Community Edition 2019.1.3\helpers\pycharm\_jb_unittest_runner.py" --target unittestdemo.MyTestCase
145+
Launching unittests with arguments python -m unittest unittestdemo.MyTestCase in F:\code\AutomatedTestingDemo
146+
147+
148+
Ran 1 test in 16.699s
149+
150+
OK
151+
152+
Process finished with exit code 0
153+
```
154+
155+
##### Test Case & Test Suite &Test Runner
156+
157+
官网的含义介绍:
158+
159+
> A test case is the smallest unit of testing. It checks for a specific response to a particular set of inputs. 测试用例是最小的测试单元。它检查对特定输入集的特定响应。
160+
>
161+
> A test suite is a collection of test cases, test suites, or both. It is used to aggregate tests taht should be executed together. 测试套件是测试用例、测试套件或两者的集合。它用于聚合应该一起执行的测试。
162+
>
163+
> A test runner is a component thich orchestrates the execution of tests and provides the outcome to the user. 测试运行器是一个组件,它协调测试的执行并向用户提供结果。
164+
165+
###### 应用Test Suite 和Test Runner 运行自动化脚本
166+
167+
```python
168+
import unittestdemo
169+
import unittest
170+
171+
172+
# 以一个类的维度去执行
173+
cases = unittest.TestLoader.loadTestsFromTestCase(unittestdemo.MyTestCase)
174+
# 可以一次添加多个cases
175+
my_suite = unittest.TestSuite([cases])
176+
177+
# 添加单个测试用例,在使用ddt后,将会不可用
178+
# my_suite = unittest.TestSuite()
179+
# my_suite.addTest(unittestdemo.MyTestCase("test_something"))
180+
181+
my_runner = unittest.TextTestRunner(verbosity=2)
182+
my_runner.run(my_suite)
183+
```
184+
185+
##### 数据驱动DDT
186+
187+
[官网](https://pypi.org/project/ddt/)
188+
189+
> DDT(Data-Driven Tests) allows you to multiply one test case by runing it with different test data, and make it appear as multiple test cases.
190+
>
191+
> DDT(数据驱动测试)允许您将一个测试用例与不同的测试数据一起运行,从而使它显示为多个测试用例。
192+
193+
###### 数据驱动DDT的使用
194+
195+
- 准备第三方库
196+
197+
> 首先安装ddt库, 其次在脚本中引入ddt
198+
199+
- 使用
200+
201+
```python
202+
import unittest
203+
from ddt import ddt, data, unpack
204+
205+
# 声明该测试类采用ddt
206+
@ddt
207+
class MyTestCase(unittest.TestCase):
208+
209+
# 使用元祖存放被测试的数据,一次只有一个参数的情况,每一组数据都会执行一次测试用例
210+
@data(1, 2, 3)
211+
def test_something(self, value):
212+
print value
213+
self.assertEqual(value, 2)
214+
215+
# 使用元祖存放被测试的数据,一次有多个参数的情况,每一组数据都会执行一次测试用例
216+
@data((1, 2), (2, 3))
217+
@unpack
218+
def test_something(self, value1, value2):
219+
print value1, value2
220+
self.assertEqual(value2, value1 + 1)
221+
222+
if __name__ == '__main__':
223+
unittest.main()
224+
225+
```
226+
227+
- 用ddt改写测试系统计算器的测试脚本
228+
229+
```python
230+
import unittest
231+
from appium import webdriver
232+
from ddt import ddt, data, unpack
233+
234+
235+
@ddt
236+
class MyTestCase(unittest.TestCase):
237+
238+
def setUp(self):
239+
desired_caps = {'platformName': 'Android', 'platformVersion': '9.0', 'deviceName': '192.168.115.101:5555',
240+
'appPackage': 'com.android.calculator2', 'appActivity': '.Calculator',
241+
"unicodeKeyboard": "True", "resetKeyboard": "True"}
242+
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
243+
244+
@data("30,352", "35,023", "12,345", "32,053")
245+
def test_something(self, expected_result):
246+
self.driver.find_element_by_id("digit_1").click()
247+
self.driver.find_element_by_id("digit_3").click()
248+
self.driver.find_element_by_id("digit_5").click()
249+
self.driver.find_element_by_id("op_add").click()
250+
self.driver.find_element_by_id("digit_8").click()
251+
self.driver.find_element_by_id("digit_9").click()
252+
self.driver.find_element_by_id("op_mul").click()
253+
self.driver.find_element_by_id("digit_3").click()
254+
self.driver.find_element_by_id("digit_9").click()
255+
self.driver.find_element_by_id("digit_2").click()
256+
self.driver.find_element_by_id("eq").click()
257+
258+
result = self.driver.find_element_by_id("result").text
259+
self.assertEqual(result, expected_result)
260+
261+
def tearDown(self):
262+
# 一定记得退出driver,不然下次运行会直接报错,除非在Appium中手动停止连接
263+
self.driver.quit()
264+
265+
266+
if __name__ == '__main__':
267+
unittest.main()
268+
269+
```
270+
271+

ddttest.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# encoding=utf-8
2+
3+
import unittest
4+
from ddt import ddt, data, unpack
5+
6+
7+
@ddt
8+
class MyTestCase(unittest.TestCase):
9+
10+
@data(1, 2, 3)
11+
def test_something(self, value):
12+
print value
13+
self.assertEqual(value, 2)
14+
15+
@data((1, 2), (2, 3))
16+
@unpack
17+
def test_something(self, value1, value2):
18+
print value1, value2
19+
self.assertEqual(value2, value1 + 1)
20+
21+
22+
if __name__ == '__main__':
23+
unittest.main()

mytestrunner.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# encoding=utf-8
2+
3+
import unittestdemo
4+
import unittest
5+
6+
7+
# 以一个类的维度去执行
8+
cases = unittest.TestLoader.loadTestsFromTestCase(unittestdemo.MyTestCase)
9+
# 可以一次添加多个cases
10+
my_suite = unittest.TestSuite([cases])
11+
12+
# 添加单个测试用例,在使用ddt后,将会不可用
13+
# my_suite = unittest.TestSuite()
14+
# my_suite.addTest(unittestdemo.MyTestCase("test_something"))
15+
16+
my_runner = unittest.TextTestRunner(verbosity=2)
17+
my_runner.run(my_suite)

test_demo/__init__.py

Whitespace-only changes.

test_demo/test_demo.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# encoding=utf-8
2+
3+
from appium import webdriver
4+
5+
desired_caps = {}
6+
desired_caps['platformName'] = 'Android'
7+
desired_caps['platformVersion'] = '9.0'
8+
desired_caps['deviceName'] = '192.168.115.101:5555'
9+
desired_caps['appPackage'] = 'com.android.calculator2'
10+
desired_caps['appActivity'] = '.Calculator'
11+
desired_caps["unicodeKeyboard"] = "True"
12+
desired_caps["resetKeyboard"] = "True"
13+
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
14+
15+
driver.find_element_by_id("digit_1").click()
16+
driver.find_element_by_id("digit_3").click()
17+
driver.find_element_by_id("digit_5").click()
18+
driver.find_element_by_id("op_add").click()
19+
driver.find_element_by_id("digit_8").click()
20+
driver.find_element_by_id("digit_9").click()
21+
driver.find_element_by_id("op_mul").click()
22+
driver.find_element_by_id("digit_3").click()
23+
driver.find_element_by_id("digit_9").click()
24+
driver.find_element_by_id("digit_2").click()
25+
driver.find_element_by_id("eq").click()
26+
27+
result = driver.find_element_by_id("result").text
28+
29+
if result == "30,352":
30+
print "pass"
31+
else:
32+
print "fail"
33+
34+
# 一定记得退出driver,不然下次运行会直接报错,除非在Appium中手动停止连接
35+
driver.quit()

unittestdemo.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# encoding=utf-8
2+
3+
4+
import unittest
5+
from appium import webdriver
6+
from ddt import ddt, data, unpack
7+
8+
9+
@ddt
10+
class MyTestCase(unittest.TestCase):
11+
12+
def setUp(self):
13+
desired_caps = {'platformName': 'Android', 'platformVersion': '9.0', 'deviceName': '192.168.115.101:5555',
14+
'appPackage': 'com.android.calculator2', 'appActivity': '.Calculator',
15+
"unicodeKeyboard": "True", "resetKeyboard": "True"}
16+
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
17+
18+
@data("30,352", "35,023", "12,345", "32,053")
19+
def test_something(self, expected_result):
20+
self.driver.find_element_by_id("digit_1").click()
21+
self.driver.find_element_by_id("digit_3").click()
22+
self.driver.find_element_by_id("digit_5").click()
23+
self.driver.find_element_by_id("op_add").click()
24+
self.driver.find_element_by_id("digit_8").click()
25+
self.driver.find_element_by_id("digit_9").click()
26+
self.driver.find_element_by_id("op_mul").click()
27+
self.driver.find_element_by_id("digit_3").click()
28+
self.driver.find_element_by_id("digit_9").click()
29+
self.driver.find_element_by_id("digit_2").click()
30+
self.driver.find_element_by_id("eq").click()
31+
32+
result = self.driver.find_element_by_id("result").text
33+
self.assertEqual(result, expected_result)
34+
35+
def tearDown(self):
36+
# 一定记得退出driver,不然下次运行会直接报错,除非在Appium中手动停止连接
37+
self.driver.quit()
38+
39+
40+
if __name__ == '__main__':
41+
unittest.main()

0 commit comments

Comments
 (0)