Wechat small program — automatic test
As for the automatic test of small program, I follow the official documents of wechat small program. I didn’t go too far, just dot, dot, dot.
The overall process is to install the test environment, set up the security Settings, then create a test folder in the project directory and create the test code files in the folder, step by step
Installation environment
Install miniprogram-Automator JDK (MiniProgram-Automator) and jEST (Front-end testing framework)
npm i miniprogram-automator jest
npm i jest -g
Copy the code
Then open the “security Settings CLI/HTTP call function” (< — _ — #>
Go inside. This is what it looks like now
Then create the applet automation test folder in the project, along with the test script index.spec.js
Write the code
To write the test code in index.spec.js, I won’t have to copy the official website directly first.
const automator = require('miniprogram-automator')
describe('index'.() = > {
let miniProgram
let page
beforeAll(async () => {
miniProgram = await automator.launch({
projectPath: '/Users/xxxxx/Desktop/company/xxxxx'
})
page = await miniProgram.reLaunch('/pages/index/index')
await page.waitFor(500)},3000000)
afterAll(async() = > {await miniProgram.close()
})
})
Copy the code
The above is the source of everything ⬆️, I will read this paragraph according to my own understanding.
The first is the introduction of the official website:
- Start and connect tools
- Restart the applet to the home page
- Disconnect and close the tool
I understand that the automatic object automator is introduced, and then the fixed method describe, callback inside the concrete event. BeforeAll before everything starts, connect project, projectPath projectPath, the complete path I wrote, is in terminal CD CD CD into my project, then PWD out path. Page then corresponds to the path the project entered when it was opened. WaitFor (500) : waitFor(500) : waitFor(500) : waitFor(500) : waitFor(500
// If the condition is string, this parameter is treated as a selector, and the wait ends when the number of elements selected by the selector is not zero.
// If the condition is number, this parameter will be regarded as the timeout period, and the wait will end after the specified time.
// If the condition is of type Function, the argument is treated as an assertion Function, and the wait ends when the Function returns true.
Copy the code
BeforeAll the second parameter is easy to understand, the wait time is 3000000 milliseconds as the initialization time, set too short it may be finished before the project is finished compiling.
AfterAll is executed afterAll methods and stuff have finished, sort of like a life cycle.
Then there is the simulation mouse, which I can only do as a level 0 test.
it('list action'.async() = > {const listHead = await page.$('.kind-list-item-hd')
expect(await listHead.attribute('class')).toBe('kind-list-item-hd')
await listHead.tap()
await page.waitFor(200)
expect(await listHead.attribute('class')).toBe(
'kind-list-item-hd kind-list-item-hd-show'.)await listHead.tap()
await page.waitFor(200)
expect(await listHead.attribute('class')).toBe('kind-list-item-hd')
await listHead.tap()
await page.waitFor(200)
const item = await page.$('.index-bd navigator')
await item.tap()
await page.waitFor(500)
expect((await miniProgram.currentPage()).path).toBe('page/component/pages/view/view')})Copy the code
As I understand it, it is a fixed method, the first parameter is the thing that the IT should do, the second parameter is the thing to do, async is synchronization. There can be many IT’s, executed from top to bottom.
Get the page node first, page.$() see this please imagine JQuery, await etc. page method is finished, so async… Await, the page method should be asynchronous. Step by step, expect is the assertion, toBe is the prediction of what expect returns, and direct translation is the expectation of what it is. Understand the applause ~!! Piapiapia ~, then whenever to add this await, as long as it is a method, add this await. Don’t forget that it doesn’t feel like linear execution. And then it’s very easy to understand. Tap () is bindtap. (await miniprogram.currentpage ()).path this is the path to the currentPage. If you switch pages, be sure page = await miniprogram.currentPage (). I forgot to mention that the IT method is placed in describe, at ⬇️. Hey hey
const automator = require('miniprogram-automator')
describe('index'.() = > {
let miniProgram
let page
beforeAll(async () => {
miniProgram = await automator.launch({
projectPath: '/Users/xxxxxxxxxx/Desktop/company/xxxxxxxx'
})
page = await miniProgram.reLaunch('/pages/index/index')
await page.waitFor(500)},3000000)
afterAll(async() = > {await miniProgram.close()
})
it('xxxxxx'.async() => {
page = await miniProgram.reLaunch('/xxxx/xxxx/xxxx? xxxx=/xxxxx/xxxxxx/xxxxx')
expect((await miniProgram.currentPage()).path).toBe('pages/index/index')})})Copy the code
Start the
Then it starts up, in Terminal, CDCDCD to the folder where the script was written, and jest index.spec.js is ready. The phenomenon is that the applet will be closed and restarted, and then execute the IT method in the script, and then close the applet and display the result in Terminal. AfterAll closes if it succeeds or fails because afterAll is set to close.
Finally summarize and try more
It’s pretty easy to use initially, but of course I know all the classes in advance, like when I review the elements on the page. Those methods are in the official document while writing, access to the page element is actually a kind of data, loop what you want to hello how hello. The two dollar sign is to get multiple elements and return an array. Remind each IT method not to execute more than 5s, or it will time out. Here are some ways to break your heart. There are a number of methods for page, but I won’t go into them because of the simplicity of the name. You can see it for yourself. It’s very simple. It’s good to distinguish between methods and properties when you use them. For example, input is a method. I write with equal sign all the time, so why can’t INPUT be assigned? Look closely and see that it is a method. I’m sorry I don’t have enough brains.
it('xxxxxxxx'.async() = > {const meetingRes = await page.$$('.listBar');
for(let i = -1; ++i < meetingRes.length; ) {if (await meetingRes[i].text() === 'xxxxxx') {
awaitmeetingRes[i].tap(); }}await page.waitFor();
page = await miniProgram.currentPage();
})
Copy the code
it('xxxxxx'.async() = > {const inputList = await page.$$('.weui-input')
expect(inputList.length).toBe(6);
let index = -1;
while(++index < inputList.length) {
switch(await inputList[index].attribute('data-field')) {
case 'xxxxx' || 'xxxx':
console.log(index)
await inputList[index].input('xxxx' + new Date().getTime())
break;
case 'xxxxxx':
await inputList[index].tap();
await page.waitFor(500);
expect((await miniProgram.currentPage()).path).toBe('pages/xxx/xxxx/xxxxx')
page = await miniProgram.currentPage();
const meetingRoomDetail = await page.$$('.xxxx')
await meetingRoomDetail[0].tap();
await page.waitFor(500);
expect((await miniProgram.currentPage()).path).toBe('pages/xxxx/xxxxx')
page = await miniProgram.currentPage();
break;
case 'xxxxxx':
await inputList[index].tap();
await page.waitFor(500);
const confirmdate = await page.$('.van-picker__confirm')
await confirmdate.tap();
break;
case 'xxxxxx':
await inputList[index].tap();
await page.waitFor(500)
const periodList = await page.$$('.van-checkbox__icon');
let i = periodList.length;
let count = 0;
while(--i >= 0) {
if (periodList[i].attribute('class') = = ='van-checkbox__icon van-checkbox__icon--round' && count === 0) {
count++
await periodList[i].tap();
break; }}const confirmperiod = await page.$('.van-picker__confirm')
await confirmperiod.tap();
break;
case 'xxxxxx':
await inputList[index].tap();
await page.waitFor(500);
expect((await miniProgram.currentPage()).path).toBe('pages/xxxx/xxxx/xxxxx')
page = await miniProgram.currentPage();
const nameinput = await page.$('.van-field__input')
await nameinput.input('xxxx')
await page.waitFor(1200);
const searchList = await page.$$('.xxxx');
await searchList[0].tap();
const closeSearch = await page.$('.xxxx')
await closeSearch.tap();
const confirm = await page.$('.xxxx')
await confirm.tap();
await page.waitFor(500);
expect((await miniProgram.currentPage()).path).toBe('pages/xxxx/xxxx')
page = await miniProgram.currentPage();
break;
default:
break; }}const submit = await page.$('.weui-btn')
expect(submit.tagName).toBe('button')
expect(await submit.text()).toBe('sure')
await submit.tap();
await page.waitFor(500)
expect((await miniProgram.currentPage()).path).toBe('pages/xxxx/xxxxx')
page = await miniProgram.currentPage();
})
Copy the code
I tried it, and wrote an automated script, not to mention really let me detect the problem. Automated scripts really make sense, as in projects I’m writing now, where iteration is fast. I also can’t guarantee that every iteration won’t affect other features, or that something unintentionally blocks a feature change, as well as being a proactive way to find problems. Use magic to defeat magic, use program to find the problem of program, HMMM ~ something like that. There is a place where the source of everything said before, there is the initial page can be changed into the small program, so if there is a jump from the public to the small program in a page of the business scene, you can try to simulate here. After all, the public can not jump experience version, each submission of audit and a long time.
Happy time is here. Happy New Year to you all. Cheers to My Life. 🍻