Kea2-python 1.0.3__tar.gz → 1.0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/PKG-INFO +54 -19
- {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/SOURCES.txt +3 -1
- {kea2_python-1.0.3 → kea2_python-1.0.5}/PKG-INFO +54 -19
- {kea2_python-1.0.3 → kea2_python-1.0.5}/README.md +53 -18
- kea2_python-1.0.5/kea2/__init__.py +3 -0
- kea2_python-1.0.5/kea2/assets/fastbot_libs/arm64-v8a/libfastbot_native.so +0 -0
- kea2_python-1.0.5/kea2/assets/fastbot_libs/armeabi-v7a/libfastbot_native.so +0 -0
- kea2_python-1.0.5/kea2/assets/fastbot_libs/x86/libfastbot_native.so +0 -0
- kea2_python-1.0.5/kea2/assets/fastbot_libs/x86_64/libfastbot_native.so +0 -0
- kea2_python-1.0.5/kea2/assets/monkeyq.jar +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/cli.py +6 -7
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/fastbotManager.py +61 -51
- kea2_python-1.0.5/kea2/kea2_api.py +166 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/keaUtils.py +54 -24
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/kea_launcher.py +12 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/bug_report_generator.py +33 -5
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/mixin.py +23 -9
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/report_merger.py +91 -6
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/templates/bug_report_template.html +208 -12
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/resultSyncer.py +9 -13
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/u2Driver.py +78 -67
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/utils.py +29 -1
- {kea2_python-1.0.3 → kea2_python-1.0.5}/pyproject.toml +1 -1
- kea2_python-1.0.5/tests/test_xpath.py +67 -0
- kea2_python-1.0.3/kea2/__init__.py +0 -1
- kea2_python-1.0.3/kea2/assets/fastbot_libs/arm64-v8a/libfastbot_native.so +0 -0
- kea2_python-1.0.3/kea2/assets/fastbot_libs/armeabi-v7a/libfastbot_native.so +0 -0
- kea2_python-1.0.3/kea2/assets/fastbot_libs/x86/libfastbot_native.so +0 -0
- kea2_python-1.0.3/kea2/assets/fastbot_libs/x86_64/libfastbot_native.so +0 -0
- kea2_python-1.0.3/kea2/assets/monkeyq.jar +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/dependency_links.txt +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/entry_points.txt +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/requires.txt +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/top_level.txt +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/LICENSE +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/absDriver.py +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/adbUtils.py +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/config_version.json +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot-thirdpart.jar +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/abl.strings +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/awl.strings +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/max.config +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/max.fuzzing.strings +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/max.schema.strings +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/max.strings +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/max.tree.pruning +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/teardown.py +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/widget.block.py +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/framework.jar +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/kea2-thirdpart.jar +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/quicktest.py +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/logWatcher.py +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/mixin.py +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/__init__.py +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/templates/merged_bug_report_template.html +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/utils.py +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/version_manager.py +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/setup.cfg +0 -0
- {kea2_python-1.0.3 → kea2_python-1.0.5}/tests/test_u2Selector.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Kea2-python
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: A python library for supporting and customizing automated UI testing for mobile apps
|
|
5
5
|
Author-email: Xixian Liang <xixian@stu.ecnu.edu.cn>
|
|
6
6
|
Requires-Python: >=3.8
|
|
@@ -21,13 +21,17 @@ Dynamic: license-file
|
|
|
21
21
|
[](https://deepwiki.com/ecnusse/Kea2)
|
|
22
22
|
|
|
23
23
|
<div>
|
|
24
|
-
<img src="https://github.com/user-attachments/assets/
|
|
24
|
+
<img src="https://github.com/user-attachments/assets/8d9f8750-1e10-411b-a49f-7d8367bbe9fe" style="border-radius: 14px; width: 20%; height: 20%;"/>
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
|
+
|
|
27
28
|
Please contact Xixian Liang at [xixian@stu.ecnu.edu.cn](xixian@stu.ecnu.edu.cn) with your Wechat ID / QR code to be invited to the WeChat discussion group. Of course, we are also ready on GitHub to answer your questions/feedback.
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
[https://
|
|
30
|
+
#### Github repo [https://github.com/ecnusse/Kea2](https://github.com/ecnusse/Kea2)
|
|
31
|
+
#### Gitee mirror [https://gitee.com/XixianLiang/Kea2](https://gitee.com/XixianLiang/Kea2)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
31
35
|
|
|
32
36
|
### [点击此处:查看中文文档](README_cn.md)
|
|
33
37
|
|
|
@@ -74,7 +78,7 @@ Kea2 currently targets [Android](https://en.wikipedia.org/wiki/Android_(operatin
|
|
|
74
78
|
|
|
75
79
|
Kea2 (and its idea) has been used/integrated by
|
|
76
80
|
|
|
77
|
-
- [OPay Business](https://play.google.com/store/apps/details?id=team.opay.pay.merchant.service) --- a financial & payment app. OPay uses Kea2 for regression testing on POS machines and mobile devices.
|
|
81
|
+
- [OPay Business](https://play.google.com/store/apps/details?id=team.opay.pay.merchant.service) --- a financial & payment app (2 millions of active users daily). OPay uses Kea2 for regression testing on POS machines and mobile devices.
|
|
78
82
|
|
|
79
83
|
- [WeChat's iExplorer]() --- WeChat's in-house testing platform (coming with an interactive UI-based tool to ease writing scripts)
|
|
80
84
|
|
|
@@ -208,7 +212,7 @@ You can find the full example in script `quicktest.py`, and run this script with
|
|
|
208
212
|
|
|
209
213
|
```bash
|
|
210
214
|
# Launch Kea2 and load one single script quicktest.py.
|
|
211
|
-
kea2 run -p it.feio.android.omninotes.alpha --
|
|
215
|
+
kea2 run -p it.feio.android.omninotes.alpha --running-minutes 10 --throttle 200 --driver-name d propertytest discover -p quicktest.py
|
|
212
216
|
```
|
|
213
217
|
|
|
214
218
|
## Feature 3(运行增强版Fastbot:加入自动断言)
|
|
@@ -243,7 +247,8 @@ For the preceding always-holding property, we can write the following script to
|
|
|
243
247
|
)
|
|
244
248
|
def test_input_box(self):
|
|
245
249
|
|
|
246
|
-
# genenerate a random non-empty string (this is also property-based testing
|
|
250
|
+
# genenerate a random non-empty string (this is also property-based testing
|
|
251
|
+
# by feeding random text inputs!)
|
|
247
252
|
from hypothesis.strategies import text, ascii_letters
|
|
248
253
|
random_str = text(alphabet=ascii_letters).example()
|
|
249
254
|
|
|
@@ -261,9 +266,7 @@ For the preceding always-holding property, we can write the following script to
|
|
|
261
266
|
|
|
262
267
|
You can run this example by using the similar command line in Feature 2.
|
|
263
268
|
|
|
264
|
-
## Feature 4
|
|
265
|
-
|
|
266
|
-
> This feature is still under development. We are looking forward to your feedback! Contact us if you're interested in this feature.
|
|
269
|
+
## Feature 4(兼容已有脚本:通过前置脚本步骤到达特定层次)
|
|
267
270
|
|
|
268
271
|
Kea2 supports reusing existing Ui test Scripts. We are inspired by the idea that: *The existing Ui test scripts usually cover important app functionalities and can reach deep app states. Thus, they can be used as good "guiding scripts" to drive Fastbot to explore important and deep app states.*
|
|
269
272
|
|
|
@@ -271,22 +274,54 @@ For example, you may already have some existing Ui test scripts "login and add a
|
|
|
271
274
|
|
|
272
275
|
### Example
|
|
273
276
|
|
|
274
|
-
|
|
277
|
+
Here are four example scripts in hybridetest_examples, each corresponding to different forms of user scripts, showing you how to launch kea2 in the existing code.
|
|
275
278
|
|
|
276
|
-
|
|
279
|
+
Specifically:
|
|
277
280
|
|
|
278
|
-
|
|
281
|
+
* [u2_unittest_example.py](hybridtest_examples\u2_unittest_example.py) is a u2 script organized with unittest.
|
|
282
|
+
* [u2_pytest_example.py](hybridtest_examples\u2_pytest_example.py) is a u2 script organized with pytest.
|
|
283
|
+
* [appium_unittest_example.py](hybridtest_examples\appium_unittest_example.py) is an appium script organized with unittest.
|
|
284
|
+
* [appium_pytest_example.py](hybridtest_examples\appium_pytest_example.py) is an appium script organized with pytest.
|
|
279
285
|
|
|
280
|
-
|
|
286
|
+
Some notes:
|
|
281
287
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
288
|
+
1. You can control whether to execute the kea2-related code you have written by modifying the condition of 'if'. This allows you to easily enable or disable kea2 operations in the same script. Here we use environment variable as an example.
|
|
289
|
+
2. Since kea2 is driven by u2, if an appium-written script wants to launch kea2, it is necessary to first close the appium session. Remember to configure the parameter `"noReset": True` in `desired_caps` to avoid resetting the application when closing the session.
|
|
290
|
+
3. You need to insert the following code template into your existing test cases: Here, you can add your own hook logic in the commented sections, including starting or stopping the appium session, cleaning up instances, etc. This depends on how you want to design the setup and teardown. Apart from that, you only need to configure the `option` parameter and `configs_path` parameter(where your directory `configs` located, btw, `configs`'s location dependon where you executed `kea2 init`), then pass it to the `run_kea2_testing` function.
|
|
291
|
+
|
|
292
|
+
```python
|
|
293
|
+
from kea2 import Kea2Tester, Options, U2Driver
|
|
285
294
|
|
|
286
|
-
|
|
287
|
-
|
|
295
|
+
if os.environ.get('KEA2_HYBRID_MODE', '').lower() == 'true':
|
|
296
|
+
'''
|
|
297
|
+
Note: The if condition here can be modified as needed according to the actual
|
|
298
|
+
situation of the project, the form of environment variables is just an example.
|
|
299
|
+
'''
|
|
300
|
+
|
|
301
|
+
# close your driver session etc. here
|
|
302
|
+
# ...
|
|
303
|
+
|
|
304
|
+
tester = Kea2Tester()
|
|
305
|
+
result = self.tester.run_kea2_testing(
|
|
306
|
+
Options(
|
|
307
|
+
driverName="d",
|
|
308
|
+
packageNames=[PACKAGE_NAME],
|
|
309
|
+
propertytest_args=["discover", "-p", "Omninotes_Sample.py"],
|
|
310
|
+
serial=DEVICE_SERIAL,
|
|
311
|
+
running_mins=2,
|
|
312
|
+
maxStep=20
|
|
313
|
+
),
|
|
314
|
+
configs_path = None # Default, if your configs folder is located in the root directory, miss this.
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
# restart your driver session or clean instance here
|
|
318
|
+
# ...
|
|
319
|
+
|
|
320
|
+
return # this make your following steps of this testcase not work
|
|
288
321
|
```
|
|
289
322
|
|
|
323
|
+
|
|
324
|
+
|
|
290
325
|
## Test Reports(测试报告)
|
|
291
326
|
|
|
292
327
|
Kea2 automatically generates a HTML test report after each testing session. You can find the report in `output/` under your working directory.
|
|
@@ -12,6 +12,7 @@ kea2/absDriver.py
|
|
|
12
12
|
kea2/adbUtils.py
|
|
13
13
|
kea2/cli.py
|
|
14
14
|
kea2/fastbotManager.py
|
|
15
|
+
kea2/kea2_api.py
|
|
15
16
|
kea2/keaUtils.py
|
|
16
17
|
kea2/kea_launcher.py
|
|
17
18
|
kea2/logWatcher.py
|
|
@@ -46,4 +47,5 @@ kea2/report/report_merger.py
|
|
|
46
47
|
kea2/report/utils.py
|
|
47
48
|
kea2/report/templates/bug_report_template.html
|
|
48
49
|
kea2/report/templates/merged_bug_report_template.html
|
|
49
|
-
tests/test_u2Selector.py
|
|
50
|
+
tests/test_u2Selector.py
|
|
51
|
+
tests/test_xpath.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Kea2-python
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: A python library for supporting and customizing automated UI testing for mobile apps
|
|
5
5
|
Author-email: Xixian Liang <xixian@stu.ecnu.edu.cn>
|
|
6
6
|
Requires-Python: >=3.8
|
|
@@ -21,13 +21,17 @@ Dynamic: license-file
|
|
|
21
21
|
[](https://deepwiki.com/ecnusse/Kea2)
|
|
22
22
|
|
|
23
23
|
<div>
|
|
24
|
-
<img src="https://github.com/user-attachments/assets/
|
|
24
|
+
<img src="https://github.com/user-attachments/assets/8d9f8750-1e10-411b-a49f-7d8367bbe9fe" style="border-radius: 14px; width: 20%; height: 20%;"/>
|
|
25
25
|
</div>
|
|
26
26
|
|
|
27
|
+
|
|
27
28
|
Please contact Xixian Liang at [xixian@stu.ecnu.edu.cn](xixian@stu.ecnu.edu.cn) with your Wechat ID / QR code to be invited to the WeChat discussion group. Of course, we are also ready on GitHub to answer your questions/feedback.
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
[https://
|
|
30
|
+
#### Github repo [https://github.com/ecnusse/Kea2](https://github.com/ecnusse/Kea2)
|
|
31
|
+
#### Gitee mirror [https://gitee.com/XixianLiang/Kea2](https://gitee.com/XixianLiang/Kea2)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
31
35
|
|
|
32
36
|
### [点击此处:查看中文文档](README_cn.md)
|
|
33
37
|
|
|
@@ -74,7 +78,7 @@ Kea2 currently targets [Android](https://en.wikipedia.org/wiki/Android_(operatin
|
|
|
74
78
|
|
|
75
79
|
Kea2 (and its idea) has been used/integrated by
|
|
76
80
|
|
|
77
|
-
- [OPay Business](https://play.google.com/store/apps/details?id=team.opay.pay.merchant.service) --- a financial & payment app. OPay uses Kea2 for regression testing on POS machines and mobile devices.
|
|
81
|
+
- [OPay Business](https://play.google.com/store/apps/details?id=team.opay.pay.merchant.service) --- a financial & payment app (2 millions of active users daily). OPay uses Kea2 for regression testing on POS machines and mobile devices.
|
|
78
82
|
|
|
79
83
|
- [WeChat's iExplorer]() --- WeChat's in-house testing platform (coming with an interactive UI-based tool to ease writing scripts)
|
|
80
84
|
|
|
@@ -208,7 +212,7 @@ You can find the full example in script `quicktest.py`, and run this script with
|
|
|
208
212
|
|
|
209
213
|
```bash
|
|
210
214
|
# Launch Kea2 and load one single script quicktest.py.
|
|
211
|
-
kea2 run -p it.feio.android.omninotes.alpha --
|
|
215
|
+
kea2 run -p it.feio.android.omninotes.alpha --running-minutes 10 --throttle 200 --driver-name d propertytest discover -p quicktest.py
|
|
212
216
|
```
|
|
213
217
|
|
|
214
218
|
## Feature 3(运行增强版Fastbot:加入自动断言)
|
|
@@ -243,7 +247,8 @@ For the preceding always-holding property, we can write the following script to
|
|
|
243
247
|
)
|
|
244
248
|
def test_input_box(self):
|
|
245
249
|
|
|
246
|
-
# genenerate a random non-empty string (this is also property-based testing
|
|
250
|
+
# genenerate a random non-empty string (this is also property-based testing
|
|
251
|
+
# by feeding random text inputs!)
|
|
247
252
|
from hypothesis.strategies import text, ascii_letters
|
|
248
253
|
random_str = text(alphabet=ascii_letters).example()
|
|
249
254
|
|
|
@@ -261,9 +266,7 @@ For the preceding always-holding property, we can write the following script to
|
|
|
261
266
|
|
|
262
267
|
You can run this example by using the similar command line in Feature 2.
|
|
263
268
|
|
|
264
|
-
## Feature 4
|
|
265
|
-
|
|
266
|
-
> This feature is still under development. We are looking forward to your feedback! Contact us if you're interested in this feature.
|
|
269
|
+
## Feature 4(兼容已有脚本:通过前置脚本步骤到达特定层次)
|
|
267
270
|
|
|
268
271
|
Kea2 supports reusing existing Ui test Scripts. We are inspired by the idea that: *The existing Ui test scripts usually cover important app functionalities and can reach deep app states. Thus, they can be used as good "guiding scripts" to drive Fastbot to explore important and deep app states.*
|
|
269
272
|
|
|
@@ -271,22 +274,54 @@ For example, you may already have some existing Ui test scripts "login and add a
|
|
|
271
274
|
|
|
272
275
|
### Example
|
|
273
276
|
|
|
274
|
-
|
|
277
|
+
Here are four example scripts in hybridetest_examples, each corresponding to different forms of user scripts, showing you how to launch kea2 in the existing code.
|
|
275
278
|
|
|
276
|
-
|
|
279
|
+
Specifically:
|
|
277
280
|
|
|
278
|
-
|
|
281
|
+
* [u2_unittest_example.py](hybridtest_examples\u2_unittest_example.py) is a u2 script organized with unittest.
|
|
282
|
+
* [u2_pytest_example.py](hybridtest_examples\u2_pytest_example.py) is a u2 script organized with pytest.
|
|
283
|
+
* [appium_unittest_example.py](hybridtest_examples\appium_unittest_example.py) is an appium script organized with unittest.
|
|
284
|
+
* [appium_pytest_example.py](hybridtest_examples\appium_pytest_example.py) is an appium script organized with pytest.
|
|
279
285
|
|
|
280
|
-
|
|
286
|
+
Some notes:
|
|
281
287
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
288
|
+
1. You can control whether to execute the kea2-related code you have written by modifying the condition of 'if'. This allows you to easily enable or disable kea2 operations in the same script. Here we use environment variable as an example.
|
|
289
|
+
2. Since kea2 is driven by u2, if an appium-written script wants to launch kea2, it is necessary to first close the appium session. Remember to configure the parameter `"noReset": True` in `desired_caps` to avoid resetting the application when closing the session.
|
|
290
|
+
3. You need to insert the following code template into your existing test cases: Here, you can add your own hook logic in the commented sections, including starting or stopping the appium session, cleaning up instances, etc. This depends on how you want to design the setup and teardown. Apart from that, you only need to configure the `option` parameter and `configs_path` parameter(where your directory `configs` located, btw, `configs`'s location dependon where you executed `kea2 init`), then pass it to the `run_kea2_testing` function.
|
|
291
|
+
|
|
292
|
+
```python
|
|
293
|
+
from kea2 import Kea2Tester, Options, U2Driver
|
|
285
294
|
|
|
286
|
-
|
|
287
|
-
|
|
295
|
+
if os.environ.get('KEA2_HYBRID_MODE', '').lower() == 'true':
|
|
296
|
+
'''
|
|
297
|
+
Note: The if condition here can be modified as needed according to the actual
|
|
298
|
+
situation of the project, the form of environment variables is just an example.
|
|
299
|
+
'''
|
|
300
|
+
|
|
301
|
+
# close your driver session etc. here
|
|
302
|
+
# ...
|
|
303
|
+
|
|
304
|
+
tester = Kea2Tester()
|
|
305
|
+
result = self.tester.run_kea2_testing(
|
|
306
|
+
Options(
|
|
307
|
+
driverName="d",
|
|
308
|
+
packageNames=[PACKAGE_NAME],
|
|
309
|
+
propertytest_args=["discover", "-p", "Omninotes_Sample.py"],
|
|
310
|
+
serial=DEVICE_SERIAL,
|
|
311
|
+
running_mins=2,
|
|
312
|
+
maxStep=20
|
|
313
|
+
),
|
|
314
|
+
configs_path = None # Default, if your configs folder is located in the root directory, miss this.
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
# restart your driver session or clean instance here
|
|
318
|
+
# ...
|
|
319
|
+
|
|
320
|
+
return # this make your following steps of this testcase not work
|
|
288
321
|
```
|
|
289
322
|
|
|
323
|
+
|
|
324
|
+
|
|
290
325
|
## Test Reports(测试报告)
|
|
291
326
|
|
|
292
327
|
Kea2 automatically generates a HTML test report after each testing session. You can find the report in `output/` under your working directory.
|
|
@@ -6,13 +6,17 @@
|
|
|
6
6
|
[](https://deepwiki.com/ecnusse/Kea2)
|
|
7
7
|
|
|
8
8
|
<div>
|
|
9
|
-
<img src="https://github.com/user-attachments/assets/
|
|
9
|
+
<img src="https://github.com/user-attachments/assets/8d9f8750-1e10-411b-a49f-7d8367bbe9fe" style="border-radius: 14px; width: 20%; height: 20%;"/>
|
|
10
10
|
</div>
|
|
11
11
|
|
|
12
|
+
|
|
12
13
|
Please contact Xixian Liang at [xixian@stu.ecnu.edu.cn](xixian@stu.ecnu.edu.cn) with your Wechat ID / QR code to be invited to the WeChat discussion group. Of course, we are also ready on GitHub to answer your questions/feedback.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
[https://
|
|
15
|
+
#### Github repo [https://github.com/ecnusse/Kea2](https://github.com/ecnusse/Kea2)
|
|
16
|
+
#### Gitee mirror [https://gitee.com/XixianLiang/Kea2](https://gitee.com/XixianLiang/Kea2)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
16
20
|
|
|
17
21
|
### [点击此处:查看中文文档](README_cn.md)
|
|
18
22
|
|
|
@@ -59,7 +63,7 @@ Kea2 currently targets [Android](https://en.wikipedia.org/wiki/Android_(operatin
|
|
|
59
63
|
|
|
60
64
|
Kea2 (and its idea) has been used/integrated by
|
|
61
65
|
|
|
62
|
-
- [OPay Business](https://play.google.com/store/apps/details?id=team.opay.pay.merchant.service) --- a financial & payment app. OPay uses Kea2 for regression testing on POS machines and mobile devices.
|
|
66
|
+
- [OPay Business](https://play.google.com/store/apps/details?id=team.opay.pay.merchant.service) --- a financial & payment app (2 millions of active users daily). OPay uses Kea2 for regression testing on POS machines and mobile devices.
|
|
63
67
|
|
|
64
68
|
- [WeChat's iExplorer]() --- WeChat's in-house testing platform (coming with an interactive UI-based tool to ease writing scripts)
|
|
65
69
|
|
|
@@ -193,7 +197,7 @@ You can find the full example in script `quicktest.py`, and run this script with
|
|
|
193
197
|
|
|
194
198
|
```bash
|
|
195
199
|
# Launch Kea2 and load one single script quicktest.py.
|
|
196
|
-
kea2 run -p it.feio.android.omninotes.alpha --
|
|
200
|
+
kea2 run -p it.feio.android.omninotes.alpha --running-minutes 10 --throttle 200 --driver-name d propertytest discover -p quicktest.py
|
|
197
201
|
```
|
|
198
202
|
|
|
199
203
|
## Feature 3(运行增强版Fastbot:加入自动断言)
|
|
@@ -228,7 +232,8 @@ For the preceding always-holding property, we can write the following script to
|
|
|
228
232
|
)
|
|
229
233
|
def test_input_box(self):
|
|
230
234
|
|
|
231
|
-
# genenerate a random non-empty string (this is also property-based testing
|
|
235
|
+
# genenerate a random non-empty string (this is also property-based testing
|
|
236
|
+
# by feeding random text inputs!)
|
|
232
237
|
from hypothesis.strategies import text, ascii_letters
|
|
233
238
|
random_str = text(alphabet=ascii_letters).example()
|
|
234
239
|
|
|
@@ -246,9 +251,7 @@ For the preceding always-holding property, we can write the following script to
|
|
|
246
251
|
|
|
247
252
|
You can run this example by using the similar command line in Feature 2.
|
|
248
253
|
|
|
249
|
-
## Feature 4
|
|
250
|
-
|
|
251
|
-
> This feature is still under development. We are looking forward to your feedback! Contact us if you're interested in this feature.
|
|
254
|
+
## Feature 4(兼容已有脚本:通过前置脚本步骤到达特定层次)
|
|
252
255
|
|
|
253
256
|
Kea2 supports reusing existing Ui test Scripts. We are inspired by the idea that: *The existing Ui test scripts usually cover important app functionalities and can reach deep app states. Thus, they can be used as good "guiding scripts" to drive Fastbot to explore important and deep app states.*
|
|
254
257
|
|
|
@@ -256,22 +259,54 @@ For example, you may already have some existing Ui test scripts "login and add a
|
|
|
256
259
|
|
|
257
260
|
### Example
|
|
258
261
|
|
|
259
|
-
|
|
262
|
+
Here are four example scripts in hybridetest_examples, each corresponding to different forms of user scripts, showing you how to launch kea2 in the existing code.
|
|
260
263
|
|
|
261
|
-
|
|
264
|
+
Specifically:
|
|
262
265
|
|
|
263
|
-
|
|
266
|
+
* [u2_unittest_example.py](hybridtest_examples\u2_unittest_example.py) is a u2 script organized with unittest.
|
|
267
|
+
* [u2_pytest_example.py](hybridtest_examples\u2_pytest_example.py) is a u2 script organized with pytest.
|
|
268
|
+
* [appium_unittest_example.py](hybridtest_examples\appium_unittest_example.py) is an appium script organized with unittest.
|
|
269
|
+
* [appium_pytest_example.py](hybridtest_examples\appium_pytest_example.py) is an appium script organized with pytest.
|
|
264
270
|
|
|
265
|
-
|
|
271
|
+
Some notes:
|
|
266
272
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
273
|
+
1. You can control whether to execute the kea2-related code you have written by modifying the condition of 'if'. This allows you to easily enable or disable kea2 operations in the same script. Here we use environment variable as an example.
|
|
274
|
+
2. Since kea2 is driven by u2, if an appium-written script wants to launch kea2, it is necessary to first close the appium session. Remember to configure the parameter `"noReset": True` in `desired_caps` to avoid resetting the application when closing the session.
|
|
275
|
+
3. You need to insert the following code template into your existing test cases: Here, you can add your own hook logic in the commented sections, including starting or stopping the appium session, cleaning up instances, etc. This depends on how you want to design the setup and teardown. Apart from that, you only need to configure the `option` parameter and `configs_path` parameter(where your directory `configs` located, btw, `configs`'s location dependon where you executed `kea2 init`), then pass it to the `run_kea2_testing` function.
|
|
276
|
+
|
|
277
|
+
```python
|
|
278
|
+
from kea2 import Kea2Tester, Options, U2Driver
|
|
270
279
|
|
|
271
|
-
|
|
272
|
-
|
|
280
|
+
if os.environ.get('KEA2_HYBRID_MODE', '').lower() == 'true':
|
|
281
|
+
'''
|
|
282
|
+
Note: The if condition here can be modified as needed according to the actual
|
|
283
|
+
situation of the project, the form of environment variables is just an example.
|
|
284
|
+
'''
|
|
285
|
+
|
|
286
|
+
# close your driver session etc. here
|
|
287
|
+
# ...
|
|
288
|
+
|
|
289
|
+
tester = Kea2Tester()
|
|
290
|
+
result = self.tester.run_kea2_testing(
|
|
291
|
+
Options(
|
|
292
|
+
driverName="d",
|
|
293
|
+
packageNames=[PACKAGE_NAME],
|
|
294
|
+
propertytest_args=["discover", "-p", "Omninotes_Sample.py"],
|
|
295
|
+
serial=DEVICE_SERIAL,
|
|
296
|
+
running_mins=2,
|
|
297
|
+
maxStep=20
|
|
298
|
+
),
|
|
299
|
+
configs_path = None # Default, if your configs folder is located in the root directory, miss this.
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
# restart your driver session or clean instance here
|
|
303
|
+
# ...
|
|
304
|
+
|
|
305
|
+
return # this make your following steps of this testcase not work
|
|
273
306
|
```
|
|
274
307
|
|
|
308
|
+
|
|
309
|
+
|
|
275
310
|
## Test Reports(测试报告)
|
|
276
311
|
|
|
277
312
|
Kea2 automatically generates a HTML test report after each testing session. You can find the report in `output/` under your working directory.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -95,13 +95,12 @@ def cmd_merge(args):
|
|
|
95
95
|
# Merge test reports
|
|
96
96
|
merged_report = merger.merge_reports(args.paths, args.output)
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
print(f"📈 Merged {merge_summary.get('merged_directories', 0)} directories", flush=True)
|
|
98
|
+
if merged_report is not None:
|
|
99
|
+
print(f"✅ Test reports merged successfully!", flush=True)
|
|
100
|
+
print(f"📊 Merged report: {merged_report}", flush=True)
|
|
101
|
+
# Get merge summary
|
|
102
|
+
merge_summary = merger.get_merge_summary()
|
|
103
|
+
print(f"📈 Merged {merge_summary.get('merged_directories', 0)} directories", flush=True)
|
|
105
104
|
|
|
106
105
|
except Exception as e:
|
|
107
106
|
logger.error(f"Error during merge operation: {e}")
|
|
@@ -41,62 +41,12 @@ class FastbotManager:
|
|
|
41
41
|
:params: port: the listening port for script driver
|
|
42
42
|
:return: the fastbot daemon thread
|
|
43
43
|
"""
|
|
44
|
-
cur_dir = Path(__file__).parent
|
|
45
|
-
self.dev.sync.push(
|
|
46
|
-
Path.joinpath(cur_dir, "assets/monkeyq.jar"),
|
|
47
|
-
"/sdcard/monkeyq.jar"
|
|
48
|
-
)
|
|
49
|
-
self.dev.sync.push(
|
|
50
|
-
Path.joinpath(cur_dir, "assets/fastbot-thirdpart.jar"),
|
|
51
|
-
"/sdcard/fastbot-thirdpart.jar",
|
|
52
|
-
)
|
|
53
|
-
self.dev.sync.push(
|
|
54
|
-
Path.joinpath(cur_dir, "assets/kea2-thirdpart.jar"),
|
|
55
|
-
"/sdcard/kea2-thirdpart.jar",
|
|
56
|
-
)
|
|
57
|
-
self.dev.sync.push(
|
|
58
|
-
Path.joinpath(cur_dir, "assets/framework.jar"),
|
|
59
|
-
"/sdcard/framework.jar",
|
|
60
|
-
)
|
|
61
|
-
self.dev.sync.push(
|
|
62
|
-
Path.joinpath(cur_dir, "assets/fastbot_libs/arm64-v8a/libfastbot_native.so"),
|
|
63
|
-
"/data/local/tmp/arm64-v8a/libfastbot_native.so",
|
|
64
|
-
)
|
|
65
|
-
self.dev.sync.push(
|
|
66
|
-
Path.joinpath(cur_dir, "assets/fastbot_libs/armeabi-v7a/libfastbot_native.so"),
|
|
67
|
-
"/data/local/tmp/armeabi-v7a/libfastbot_native.so",
|
|
68
|
-
)
|
|
69
|
-
self.dev.sync.push(
|
|
70
|
-
Path.joinpath(cur_dir, "assets/fastbot_libs/x86/libfastbot_native.so"),
|
|
71
|
-
"/data/local/tmp/x86/libfastbot_native.so",
|
|
72
|
-
)
|
|
73
|
-
self.dev.sync.push(
|
|
74
|
-
Path.joinpath(cur_dir, "assets/fastbot_libs/x86_64/libfastbot_native.so"),
|
|
75
|
-
"/data/local/tmp/x86_64/libfastbot_native.so",
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
cwd = getProjectRoot()
|
|
79
|
-
whitelist = self.options.act_whitelist_file
|
|
80
|
-
blacklist = self.options.act_blacklist_file
|
|
81
|
-
if bool(whitelist) ^ bool(blacklist):
|
|
82
|
-
if whitelist:
|
|
83
|
-
file_to_push = cwd / 'configs' / 'awl.strings'
|
|
84
|
-
remote_path = whitelist
|
|
85
|
-
else:
|
|
86
|
-
file_to_push = cwd / 'configs' / 'abl.strings'
|
|
87
|
-
remote_path = blacklist
|
|
88
|
-
|
|
89
|
-
self.dev.sync.push(
|
|
90
|
-
file_to_push,
|
|
91
|
-
remote_path
|
|
92
|
-
)
|
|
93
44
|
|
|
45
|
+
self._push_libs()
|
|
94
46
|
t = self._startFastbotService()
|
|
95
47
|
logger.info("Running Fastbot...")
|
|
96
|
-
|
|
97
48
|
return t
|
|
98
49
|
|
|
99
|
-
|
|
100
50
|
def check_alive(self):
|
|
101
51
|
"""
|
|
102
52
|
check if the script driver and proxy server are alive.
|
|
@@ -179,10 +129,70 @@ class FastbotManager:
|
|
|
179
129
|
path="/dumpHierarchy",
|
|
180
130
|
)
|
|
181
131
|
return r.json()['result']
|
|
132
|
+
|
|
133
|
+
@retry(Exception, tries=2, delay=2)
|
|
134
|
+
def sendInfo(self, info: str):
|
|
135
|
+
r = self.request(
|
|
136
|
+
method="POST",
|
|
137
|
+
path="/sendInfo",
|
|
138
|
+
data=info
|
|
139
|
+
)
|
|
182
140
|
|
|
183
141
|
@property
|
|
184
142
|
def device_output_dir(self):
|
|
185
143
|
return self._device_output_dir
|
|
144
|
+
|
|
145
|
+
def _push_libs(self):
|
|
146
|
+
logger.info("Pushing Fastbot libraries to device...")
|
|
147
|
+
cur_dir = Path(__file__).parent
|
|
148
|
+
self.dev.sync.push(
|
|
149
|
+
Path.joinpath(cur_dir, "assets/monkeyq.jar"),
|
|
150
|
+
"/sdcard/monkeyq.jar"
|
|
151
|
+
)
|
|
152
|
+
self.dev.sync.push(
|
|
153
|
+
Path.joinpath(cur_dir, "assets/fastbot-thirdpart.jar"),
|
|
154
|
+
"/sdcard/fastbot-thirdpart.jar",
|
|
155
|
+
)
|
|
156
|
+
self.dev.sync.push(
|
|
157
|
+
Path.joinpath(cur_dir, "assets/kea2-thirdpart.jar"),
|
|
158
|
+
"/sdcard/kea2-thirdpart.jar",
|
|
159
|
+
)
|
|
160
|
+
self.dev.sync.push(
|
|
161
|
+
Path.joinpath(cur_dir, "assets/framework.jar"),
|
|
162
|
+
"/sdcard/framework.jar",
|
|
163
|
+
)
|
|
164
|
+
self.dev.sync.push(
|
|
165
|
+
Path.joinpath(cur_dir, "assets/fastbot_libs/arm64-v8a/libfastbot_native.so"),
|
|
166
|
+
"/data/local/tmp/arm64-v8a/libfastbot_native.so",
|
|
167
|
+
)
|
|
168
|
+
self.dev.sync.push(
|
|
169
|
+
Path.joinpath(cur_dir, "assets/fastbot_libs/armeabi-v7a/libfastbot_native.so"),
|
|
170
|
+
"/data/local/tmp/armeabi-v7a/libfastbot_native.so",
|
|
171
|
+
)
|
|
172
|
+
self.dev.sync.push(
|
|
173
|
+
Path.joinpath(cur_dir, "assets/fastbot_libs/x86/libfastbot_native.so"),
|
|
174
|
+
"/data/local/tmp/x86/libfastbot_native.so",
|
|
175
|
+
)
|
|
176
|
+
self.dev.sync.push(
|
|
177
|
+
Path.joinpath(cur_dir, "assets/fastbot_libs/x86_64/libfastbot_native.so"),
|
|
178
|
+
"/data/local/tmp/x86_64/libfastbot_native.so",
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
cwd = getProjectRoot()
|
|
182
|
+
whitelist = self.options.act_whitelist_file
|
|
183
|
+
blacklist = self.options.act_blacklist_file
|
|
184
|
+
if bool(whitelist) ^ bool(blacklist):
|
|
185
|
+
if whitelist:
|
|
186
|
+
file_to_push = cwd / 'configs' / 'awl.strings'
|
|
187
|
+
remote_path = whitelist
|
|
188
|
+
else:
|
|
189
|
+
file_to_push = cwd / 'configs' / 'abl.strings'
|
|
190
|
+
remote_path = blacklist
|
|
191
|
+
|
|
192
|
+
self.dev.sync.push(
|
|
193
|
+
file_to_push,
|
|
194
|
+
remote_path
|
|
195
|
+
)
|
|
186
196
|
|
|
187
197
|
def _startFastbotService(self) -> ADBStreamShell_V2:
|
|
188
198
|
shell_command = [
|