当前位置: 首页 > news >正文

小程序测试方案初探

前言

2017年1月9号微信小程序正式上线,小程序不需要安装就能使用,依托微信强大的生态环境,能做到很多H5所不能做的事情。从微信小程序发布这段时间,陆陆续续开发了不少小程序相关的项目,总结了一些通用性的组件,但是对于小程序如何做测试,依然是一头雾水,直到做了不少的项目,积累的一些经验和开源库之后才理清如何做测试,下面将会介绍如何对小程序做UI测试和单元测试。

工具的准备

  • node
  • puppeteer
  • wept
  • mocha
  • chai

介绍

node
这个应该不用多做介绍了,不过这次demo中要求node版本应该大于7.6.0,因为puppeteer要求最低版本是v6.4.0,但是因为官方示例中大量使用 async/await 等新特性,所以需要使用 v7.6.0 或更高版本的 Node,async/await能让异步回调代码更加简洁,不然整个代码都是promise.then

puppeteer
Chrome 团队出品的一款更友好的Headless Chrome Node API,用于代替用户在页面上面点击、拖拽、输入等多种操作,常见的使用场景还是应用到UI自动化测试,puppeteer可以对页面进行截图保存为图片或者PDF,解决爬虫无法实现的一些操作(异步加载页面内容) 。

类似的工具:
phantomjs
seleniumhq
nightmare

wept
wept可以让小程序脱离开发者工具或者微信客户端直接运行在浏览器上面,后台使用node,提供小程序API的模拟返回(wx.login、wx.getUserInfo等),前端实现了 view 层、service 层和控制层之间的相关通讯逻辑。

mocha
JavaScript测试框架,在浏览器和Node环境都可以使用,通过测试框架,可以为你的JavaScript代码添加相应的测试用例,使得项目代码更加强健。

chai
Chai是一个BDD/TDD模式的断言库,在node和浏览器环境都能运行,API通俗易懂,断言类型和方式丰富,搭配mocha,江湖人戏称为"抹茶"

配置环境

npm i -g wept
npm i --save-dev puppeteer mocha chai

在安装puppeteer有可能会出现以下报错

ERROR: Failed to download Chromium r508693! Set "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" env variable to skip download.
Error: Download failed: server returned code 502. URL: https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/508693/chrome-win32.zip
    at ClientRequest.https.get.response (D:\chromium\node_modules\puppeteer\utils\ChromiumDownloader.js:197:21)
    at Object.onceWrapper (events.js:316:30)
    at emitOne (events.js:115:13)
    at ClientRequest.emit (events.js:210:7)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:565:21)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:116:23)
    at Socket.socketOnData (_http_client.js:454:20)
    at emitOne (events.js:115:13)
    at Socket.emit (events.js:210:7)
    at ClientRequest.onsocket (D:\chromium\node_modules\https-proxy-agent\index.js:181:14)

其实是因为下载完puppeteer包之后有执行node install.js去下载chromium(实验版chrome),但是由于网络的原因,下载失败了,我们可以避免缺省的下载 chromium,通过设置环境变量来阻止set PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
然后手动去下载chromium,上面有给出链接https://storage.googleapis.co...

TODO

直接看官方给出的demo

const puppeteer = require('puppeteer');
(async () => {
  //这里和官方不一样的就是,需要手动指定chromium目录所在的地址(上面链接下载之后解压),headless为true则不会打开chromium
  const browser = await puppeteer.launch({executablePath: '/chromium/chrome.exe',headless: false});
  
  //相当于新建选项卡
  const page = await browser.newPage();
  //跳转到指定URL
  await page.goto('https://example.com');
  //截图
  await page.screenshot({path: 'example.png'});
  //关闭页面或者选项卡
  await browser.close();
})();

上面几行代码其实就是相当于我们日常的一些操作:打开chrome->新建选项卡->输入url并回车->页面截图->保存,也可以看出puppeteer是站在使用者的角度去设计API。

跑通测试demo之后,来试试小程序这边,首先必须让小程序跑在chrome上面,就要用到wept了。
1. 直接在小程序根目录上面执行wept
然后打开chrome,访问http://localhost:3000/#!pages/index/index ,就可以看到小程序运行在chrome上了,接下来要让puppeteer去抓取小程序里面的内容,直接上代码

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
(async () => {
        const browser = await puppeteer.launch({executablePath: '/chromium/chrome.exe',headless: true});
        const page = await browser.newPage();
        //设置展示的设备https://github.com/GoogleChrome/puppeteer/blob/master/DeviceDescriptors.js
        await page.emulate(devices['iPhone 6']);
        //多一个参数waitUntil,指跳转之后等待网络空闲之后再执行下一步操作,没有这个的话,截图很有可能是白屏,因为内容还没渲染出来
        await page.goto('http://localhost:3000/#!pages/index/index', {waitUntil: 'networkidle'});
        //小程序的内容其实是放在一个iframe里面,外面是无法直接抓取到iframe里面的内容,所以这里需要获取页面所有的iframe
        const frames = await page.frames();
        //根据iframe的name属性来获取正确的iframe
        const weChatFrame = frames.find(f => f.name() === 'view-0');
        //在上下文环境中获取需要抓取的内容
        const outerText = await weChatFrame.evaluate(() => {
        //上下文执行环境,跟H5一致
            const anchors = Array.from(document.querySelectorAll('.container'));
            return anchors.map(anchor => anchor.textContent);
        });
        console.log('the outerText: ', outerText);
        await browser.close();

})();

直接来看页面执行的效果
图片描述

这样我们就能拿到小程序的内容,便于我们后续的单元测试,接下来我们可以加入"抹茶"来测试输出是否符合预期,先上代码

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const expect = require('chai').expect;
describe('output test', () => {
    it('should return Hello 测试帐号 ', () => {
        (async () => {
            //小程序内容获取代码跟上述一致
            //...
            expect(outerText[0]).to.equal('Hello 测试帐号');
            //...
        })
    })
})

运行效果
图片描述

结语

小程序其实也有上线一个云测试,但是我觉得有个不好的地方,假如你的小程序是依赖于后台CGI返回数据作为展示,那么你必须先上线CGI才能使用云测试,不够灵活,更希望有一个能自己mock数据来测试不同情况下的小程序的展示。

本篇文章介绍使用wept和puppeteer来对小程序做E2E测试,对于测试环境和正式环境还是有差异的,比如Object.defineProperty小程序是不支持这个API的,但是测试环境是可以跑通的,当然测试环境下面也可以通过某种方式(比如delete)来禁用不支持小程序的API,从而达到测试环境尽可能的贴近小程序的正式环境。当然更希望的是小程序官方能给出相应的单元测试方案吧。

相关文章:

  • 注册界面
  • PDF 补丁丁 0.6.0.3288 版发布(修复“合并文件”功能的文件夹文件排序问题)
  • Python常用的软件包
  • 2017-2018-1 20155229 《信息安全系统设计基础》第五周学习总结
  • 项目管理碎碎念系列之一:干系人管理
  • java动态数组
  • Windows Server 2008服务器系统的远程桌面连接数量
  • 如何辨别护照的种类
  • 如何一步一步提高图像分类准确率?
  • 这样做,导出Xmanager会话文件不是难事!
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • BZOJ-3732: Network (kruskal+LCA)
  • 网络基础(持续更新)
  • Linux运维之道之admin1.1(命令行基础,目录和文件管理)
  • 《团队-科学计算器-模块开发过程》
  • 【391天】每日项目总结系列128(2018.03.03)
  • 4个实用的微服务测试策略
  • ES学习笔记(12)--Symbol
  • Flannel解读
  • git 常用命令
  • HTTP中GET与POST的区别 99%的错误认识
  • HTTP中的ETag在移动客户端的应用
  • JavaScript DOM 10 - 滚动
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • JDK 6和JDK 7中的substring()方法
  • Js基础知识(一) - 变量
  • LeetCode18.四数之和 JavaScript
  • Linux后台研发超实用命令总结
  • ubuntu 下nginx安装 并支持https协议
  • Vultr 教程目录
  • 产品三维模型在线预览
  • 关于使用markdown的方法(引自CSDN教程)
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 排序算法之--选择排序
  • 前端代码风格自动化系列(二)之Commitlint
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 数组的操作
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (四)图像的%2线性拉伸
  • (五)IO流之ByteArrayInput/OutputStream
  • (转)Sublime Text3配置Lua运行环境
  • **PHP分步表单提交思路(分页表单提交)
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .net 反编译_.net反编译的相关问题
  • .net的socket示例