Automating WeChat Mini‑Program Tests with Minium and Jest
This guide explains why manual regression testing of a WeChat mini‑program becomes a bottleneck, compares Jest‑based SDK and Minium frameworks, shows how to set up the environment, write page‑object scripts, configure and run tests, generate reports, and troubleshoot common issues.
Background and Need for Automation
The "精选" mini‑program experienced a packaging failure that caused a white‑screen on the "My Orders" page in production. Manual regression across pre‑release, experience, and production builds was time‑consuming and error‑prone, prompting the adoption of automated testing for the mini‑program.
Tool Research and Selection
1. Jest + Mini‑Program SDK
Provides a script‑driven automation SDK that can be combined with any Node.js test framework.
Jest is a zero‑configuration test runner that bundles Mocha, Chai, jsdom, and coverage tools.
Drawbacks: JavaScript‑only and limited community resources.
2. Minium Framework
Official WeChat automation framework with Python and JavaScript bindings.
Supports iOS, Android, and emulator with a single script.
Offers rich page navigation, data injection, and mock capabilities.
Drawbacks: No H5 page debugging and no plugin‑level wx API support.
3. Decision
Both tools satisfy the native page requirements, but Minium’s Python support, active maintenance, and community Q&A made it the chosen solution.
Introducing Minium
Minium wraps unittest.TestCase to provide a mini‑program testing framework. The base class MiniTest adds the following steps:
Load test configuration.
Initialize minium.Minium, minium.App, and minium.Native at the proper time.
Open the IDE and launch the mini‑program or auto‑port debugging.
Intercept assert calls to record results.
Collect runtime data and screenshots for report generation.
Using MiniTest dramatically reduces test cost.
Environment Setup
Install minium-doc (or read the online docs).
Install Python ≥ 3.8.
Install WeChat DevTools (e.g., version 1.05.2103200) and enable the CLI/HTTP service port.
In DevTools settings, set the base library version > 2.7.3.
Download and install the Minium package: pip3 install minium-latest.zip or python3 setup.py install Verify installation: minitest -v Enable CLI/HTTP in DevTools security settings (service port).
Open the automation port for the tested mini‑program (default 9420).
Writing Test Scripts
Use a Page Object pattern: each page is a class containing element locators and actions; test cases focus only on data and assertions.
1. Project Structure
cases/: test scripts and cases. case/base/: shared page methods. case/pages/: page‑object models. outputs/: generated reports. test/: test runner scripts. route.py: navigation routes.
2. Base Page Example
class BasePage:
def __init__(self, mini):
self.mini = mini
def navigate_to_open(self, route):
"""Navigate to a page (non‑tabBar) using a relative or absolute path."""
self.mini.app.navigate_to(route)
def redirect_to_open(self, route):
"""Redirect to a page, closing the current one."""
self.mini.app.redirect_to(route)
def switch_tab_open(self, route):
"""Switch to a tabBar page, closing other pages."""
self.mini.app.switch_tab(route)
@property
def current_title(self) -> str:
return self.mini.page.get_element("XXXXXX").inner_text
@property
def current_path(self) -> str:
return self.mini.page.path3. Home Page Object
from case.base.basepage import BasePage
from case.base import route
class HomePage(BasePage):
"""Home page common methods"""
locators = {
"BASE_ELEMENT": "view",
"BASE_BANNER": "首页banner元素选择器XXX"
}
subsidy_more_button = ("跳转页面的元素选择器XXX", "更多")
def check_homepage_path(self):
self.mini.assertEqual(self.current_path(), route.homepage_route)
def check_homepage_base_element(self):
self.mini.assertTrue(self.mini.page.element_is_exists(self.locators["BASE_ELEMENT"]))
self.mini.assertTrue(self.mini.page.element_is_exists(self.locators["BASE_BANNER"]))
def get_subsidy_element(self):
self.mini.page.get_element(str(self.subsidy_more_button[0]),
inner_text=str(self.subsidy_more_button[1])).click()4. Base Test Case
from pathlib import Path
import minium
class BaseCase(minium.MiniTest):
"""Test case base class"""
@classmethod
def setUpClass(cls):
super(BaseCase, cls).setUpClass()
output_dir = Path(cls.CONFIG.outputs)
if not output_dir.is_dir():
output_dir.mkdir()
@classmethod
def tearDownClass(cls):
super(BaseCase, cls).tearDownClass()
cls.app.go_home()
def setUp(self):
super(BaseCase, self).setUp()
def tearDown(self):
super(BaseCase, self).tearDown()5. Example Test Case
# coding=utf-8
from case.base import loader
from case.base.basecase import BaseCase
from case.pages.homepage import HomePage
class HomePageTest(BaseCase):
def __init__(self, methodName='runTest'):
super(HomePageTest, self).__init__(methodName)
self.homePage = HomePage(self)
def test_01_home_page_path(self):
self.homePage.check_homepage_path()
def test_02_page_base_element(self):
self.homePage.check_homepage_base_element()
def test_03_live_sale(self):
self.assertTexts(["官方补贴"], "view")
self.assertTexts(["轻松赚回早餐钱"], "view")
def test_04_open_live_sale(self):
self.homePage.get_subsidy_element()
self.page.wait_for(2)
result = self.page.wait_for("页面元素选择器xxx")
if result:
category = self.page.data['categoryList']
self.assertEquals("美食", category[0]['title'], "接口返回值包含美食模块")
self.assertEquals("美妆", category[1]['title'], "接口返回值包含美妆模块")
self.page.wait_for(2)
self.app.go_home()
if __name__ == "__main__":
loader.run(module="case.homepage_test", config="../config.json", generate_report=True)Configuration File (config.json)
{
"project_path": "XXXXX",
"dev_tool_path": "/Applications/wechatwebdevtools.app/Contents/MacOS/cli",
"debug_mode": "debug",
"test_port": 9420,
"platform": "ide",
"app": "wx",
"assert_capture": false,
"request_timeout": 60,
"remote_connect_timeout": 300,
"auto_relaunch": true
}Command‑Line Usage
Run a single test case:
minitest -m case.homepage_test --case test_07_open_live_sale -c config.json -gRun all tests defined in a suite file:
minitest -s suite.json -c config.json -gGenerating Test Reports
After execution, reports are stored under outputs/. To view them, start a static server, e.g.:
python3 -m http.server 12345 -d outputs
# Then open http://localhost:12345 in a browser.Common Issues and Fixes
Enable the automation port (9420) in the tested mini‑program.
Disable proxy settings in DevTools to avoid connection timeouts.
Version mismatch between Minium and DevTools can cause errors; use Minium 1.0.5 with DevTools 1.05.2102010.
Insufficient developer permissions may block testing; ensure the logged‑in account has access.
Screenshot capture may ignore assert_capture: false; patch minitest.py to check the flag before calling capture().
When using -p the Python path changes; prefer -m or manually add the path to PYTHONPATH.
References
WeChat official documentation.
Rethink’s articles on Minium (published on Zhihu/简书).
Youzan Coder
Official Youzan tech channel, delivering technical insights and occasional daily updates from the Youzan tech team.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
