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.
Files changed (59) hide show
  1. {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/PKG-INFO +54 -19
  2. {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/SOURCES.txt +3 -1
  3. {kea2_python-1.0.3 → kea2_python-1.0.5}/PKG-INFO +54 -19
  4. {kea2_python-1.0.3 → kea2_python-1.0.5}/README.md +53 -18
  5. kea2_python-1.0.5/kea2/__init__.py +3 -0
  6. kea2_python-1.0.5/kea2/assets/fastbot_libs/arm64-v8a/libfastbot_native.so +0 -0
  7. kea2_python-1.0.5/kea2/assets/fastbot_libs/armeabi-v7a/libfastbot_native.so +0 -0
  8. kea2_python-1.0.5/kea2/assets/fastbot_libs/x86/libfastbot_native.so +0 -0
  9. kea2_python-1.0.5/kea2/assets/fastbot_libs/x86_64/libfastbot_native.so +0 -0
  10. kea2_python-1.0.5/kea2/assets/monkeyq.jar +0 -0
  11. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/cli.py +6 -7
  12. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/fastbotManager.py +61 -51
  13. kea2_python-1.0.5/kea2/kea2_api.py +166 -0
  14. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/keaUtils.py +54 -24
  15. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/kea_launcher.py +12 -0
  16. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/bug_report_generator.py +33 -5
  17. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/mixin.py +23 -9
  18. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/report_merger.py +91 -6
  19. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/templates/bug_report_template.html +208 -12
  20. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/resultSyncer.py +9 -13
  21. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/u2Driver.py +78 -67
  22. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/utils.py +29 -1
  23. {kea2_python-1.0.3 → kea2_python-1.0.5}/pyproject.toml +1 -1
  24. kea2_python-1.0.5/tests/test_xpath.py +67 -0
  25. kea2_python-1.0.3/kea2/__init__.py +0 -1
  26. kea2_python-1.0.3/kea2/assets/fastbot_libs/arm64-v8a/libfastbot_native.so +0 -0
  27. kea2_python-1.0.3/kea2/assets/fastbot_libs/armeabi-v7a/libfastbot_native.so +0 -0
  28. kea2_python-1.0.3/kea2/assets/fastbot_libs/x86/libfastbot_native.so +0 -0
  29. kea2_python-1.0.3/kea2/assets/fastbot_libs/x86_64/libfastbot_native.so +0 -0
  30. kea2_python-1.0.3/kea2/assets/monkeyq.jar +0 -0
  31. {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/dependency_links.txt +0 -0
  32. {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/entry_points.txt +0 -0
  33. {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/requires.txt +0 -0
  34. {kea2_python-1.0.3 → kea2_python-1.0.5}/Kea2_python.egg-info/top_level.txt +0 -0
  35. {kea2_python-1.0.3 → kea2_python-1.0.5}/LICENSE +0 -0
  36. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/absDriver.py +0 -0
  37. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/adbUtils.py +0 -0
  38. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/config_version.json +0 -0
  39. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot-thirdpart.jar +0 -0
  40. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/abl.strings +0 -0
  41. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/awl.strings +0 -0
  42. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/max.config +0 -0
  43. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/max.fuzzing.strings +0 -0
  44. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/max.schema.strings +0 -0
  45. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/max.strings +0 -0
  46. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/max.tree.pruning +0 -0
  47. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/teardown.py +0 -0
  48. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/fastbot_configs/widget.block.py +0 -0
  49. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/framework.jar +0 -0
  50. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/kea2-thirdpart.jar +0 -0
  51. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/assets/quicktest.py +0 -0
  52. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/logWatcher.py +0 -0
  53. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/mixin.py +0 -0
  54. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/__init__.py +0 -0
  55. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/templates/merged_bug_report_template.html +0 -0
  56. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/report/utils.py +0 -0
  57. {kea2_python-1.0.3 → kea2_python-1.0.5}/kea2/version_manager.py +0 -0
  58. {kea2_python-1.0.3 → kea2_python-1.0.5}/setup.cfg +0 -0
  59. {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
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
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ecnusse/Kea2)
22
22
 
23
23
  <div>
24
- <img src="https://github.com/user-attachments/assets/84e47b87-2dd2-4d7e-91d1-e8c1d1db0cf4" style="border-radius: 14px; width: 20%; height: 20%;"/>
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
- ### Github repo link
30
- [https://github.com/ecnusse/Kea2](https://github.com/ecnusse/Kea2)
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 --agent u2 --running-minutes 10 --throttle 200 --driver-name d propertytest discover -p quicktest.py
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 by feeding random text inputs!)
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 (Experimental feature, 实验中,脚本与遍历的混合测试)
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
- See [guide_scripts.py](guide_scripts.py) for a full example.
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
- By the decorator `@interruptable`, you can mark the testcase as "interruptable" so that Kea2 can recognize this script and launch fuzzing test after it returns.
279
+ Specifically:
277
280
 
278
- Since the state of app is probably unpredicted after fuzzing tests, Kea2 provides a `common_teardown` function to clean up the environment between previous script and next script. The function can be manually specified in `configs/teardown.py`.
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
- You can find the full example in `guide_scripts.py`, `property_omninotes.py` and `configs/teardown.py` . You can run one of the following commands:
286
+ Some notes:
281
287
 
282
- ```bash
283
- # Guide with guide_scripts.py and launch fuzzing test after every script.
284
- kea2 run -p it.feio.android.omninotes.alpha --agent u2 --running-minutes 10 --throttle 500 --max-step 15 --driver-name d unittest discover -p guide_scripts.py
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
- # Guide with guide_scripts.py and launch fuzzing test after every script(check properties during fuzzing).
287
- kea2 run -p it.feio.android.omninotes.alpha --agent u2 --running-minutes 10 --throttle 500 --max-step 15 --driver-name d unittest discover -p guide_scripts.py propertytest discover -p quickstart2.py
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
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
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ecnusse/Kea2)
22
22
 
23
23
  <div>
24
- <img src="https://github.com/user-attachments/assets/84e47b87-2dd2-4d7e-91d1-e8c1d1db0cf4" style="border-radius: 14px; width: 20%; height: 20%;"/>
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
- ### Github repo link
30
- [https://github.com/ecnusse/Kea2](https://github.com/ecnusse/Kea2)
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 --agent u2 --running-minutes 10 --throttle 200 --driver-name d propertytest discover -p quicktest.py
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 by feeding random text inputs!)
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 (Experimental feature, 实验中,脚本与遍历的混合测试)
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
- See [guide_scripts.py](guide_scripts.py) for a full example.
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
- By the decorator `@interruptable`, you can mark the testcase as "interruptable" so that Kea2 can recognize this script and launch fuzzing test after it returns.
279
+ Specifically:
277
280
 
278
- Since the state of app is probably unpredicted after fuzzing tests, Kea2 provides a `common_teardown` function to clean up the environment between previous script and next script. The function can be manually specified in `configs/teardown.py`.
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
- You can find the full example in `guide_scripts.py`, `property_omninotes.py` and `configs/teardown.py` . You can run one of the following commands:
286
+ Some notes:
281
287
 
282
- ```bash
283
- # Guide with guide_scripts.py and launch fuzzing test after every script.
284
- kea2 run -p it.feio.android.omninotes.alpha --agent u2 --running-minutes 10 --throttle 500 --max-step 15 --driver-name d unittest discover -p guide_scripts.py
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
- # Guide with guide_scripts.py and launch fuzzing test after every script(check properties during fuzzing).
287
- kea2 run -p it.feio.android.omninotes.alpha --agent u2 --running-minutes 10 --throttle 500 --max-step 15 --driver-name d unittest discover -p guide_scripts.py propertytest discover -p quickstart2.py
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
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ecnusse/Kea2)
7
7
 
8
8
  <div>
9
- <img src="https://github.com/user-attachments/assets/84e47b87-2dd2-4d7e-91d1-e8c1d1db0cf4" style="border-radius: 14px; width: 20%; height: 20%;"/>
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
- ### Github repo link
15
- [https://github.com/ecnusse/Kea2](https://github.com/ecnusse/Kea2)
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 --agent u2 --running-minutes 10 --throttle 200 --driver-name d propertytest discover -p quicktest.py
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 by feeding random text inputs!)
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 (Experimental feature, 实验中,脚本与遍历的混合测试)
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
- See [guide_scripts.py](guide_scripts.py) for a full example.
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
- By the decorator `@interruptable`, you can mark the testcase as "interruptable" so that Kea2 can recognize this script and launch fuzzing test after it returns.
264
+ Specifically:
262
265
 
263
- Since the state of app is probably unpredicted after fuzzing tests, Kea2 provides a `common_teardown` function to clean up the environment between previous script and next script. The function can be manually specified in `configs/teardown.py`.
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
- You can find the full example in `guide_scripts.py`, `property_omninotes.py` and `configs/teardown.py` . You can run one of the following commands:
271
+ Some notes:
266
272
 
267
- ```bash
268
- # Guide with guide_scripts.py and launch fuzzing test after every script.
269
- kea2 run -p it.feio.android.omninotes.alpha --agent u2 --running-minutes 10 --throttle 500 --max-step 15 --driver-name d unittest discover -p guide_scripts.py
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
- # Guide with guide_scripts.py and launch fuzzing test after every script(check properties during fuzzing).
272
- kea2 run -p it.feio.android.omninotes.alpha --agent u2 --running-minutes 10 --throttle 500 --max-step 15 --driver-name d unittest discover -p guide_scripts.py propertytest discover -p quickstart2.py
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.
@@ -0,0 +1,3 @@
1
+ from .keaUtils import KeaTestRunner, precondition, prob, max_tries, Options, interruptable,HybridTestRunner,kea2_breakpoint
2
+ from .kea2_api import Kea2Tester
3
+ from .u2Driver import U2Driver
@@ -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
- # Print results
99
- print(f"✅ Test reports merged successfully!", flush=True)
100
- print(f"📊 Merged report: {merged_report}", flush=True)
101
-
102
- # Get merge summary
103
- merge_summary = merger.get_merge_summary()
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 = [