移动应用测试全攻略:从单元到性能的实战指南
在软件开发过程中,测试是确保应用质量的关键环节。本文将详细介绍多种测试方法和工具,包括使用 Jasmine 进行单元和集成测试、使用 PhantomJS 进行无头浏览器测试、使用 DalekJS 进行真实浏览器测试,以及使用 Appium 和 browser-perf 进行性能测试,同时还会介绍一些其他的测试工具。
1. Jasmine 集成测试
首先,我们来看一个简单的集成测试示例。假设我们要测试一个模块是否能正确读取文件并搜索特定字符串。以下是测试代码:
describe("Testing the whole module", function() {
it("read the file and search for 'dolor'", function(done) {
var app = require("../app.js");
app.read("./intro.txt")
expect(app.check("dolor")).toBe(true);
done();
});
});
为了让这个测试通过,我们需要对模块代码进行修改:
var fs = require('fs');
module.exports = {
fileContent: '',
read: function(filePath) {
var content = fs.readFileSync(filePath).toString();
this.fileContent = content;
return content;
},
check: function(word, content) {
content = content || this.fileContent;
return content.indexOf(word) >= 0 ? true : false;
}
}
这个测试的关键在于,我们不关心文件的实际内容,只关心它是否包含特定字符串。
2. 为 Sencha Touch 的 Imaginary 应用编写 Jasmine 测试
为了给 Sencha Touch 的 Imaginary 应用编写 Jasmine 测试,我们需要完成以下步骤:
1.
下载并解压 Jasmine 包
:从 http://jasmine.github.io/ 下载独立的 Jasmine 包,并解压到 Imaginary 项目的 spec/lib/jasmine 文件夹中。
2.
创建文件夹结构
:
.
├── helpers
│ └── SpecHelper.js
├── javascripts
│ ├── controller
│ ├── model
│ ├── sanitySpec.js
│ ├── store
│ └── view
├── lib
│ └── jasmine
└── spec-runner.html
- 设置 spec - runner.html :在文件开头,我们需要包含所有必需的 Jasmine 文件:
<html>
<head>
<title>Sencha Unit Test: Imaginary App Jasmine Tests</title>
<!-- Jasmine -->
<link rel="shortcut icon" type="image/png"
href="lib/jasmine/lib/jasmine-2.3.4/jasmine_favicon.png">
<link rel="stylesheet" type="text/css"
href="lib/jasmine/lib/jasmine-2.3.4/jasmine.css">
<script type="text/javascript" src="lib/jasmine/lib/jasmine-
2.3.4/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine/lib/jasmine-
2.3.4/jasmine-html.js"></script>
<script type="text/javascript" src="lib/jasmine/lib/jasmine-
2.3.4/boot.js"></script>
<!-- CODE TO TEST -->
<!-- UNIT TEST CLASSES -->
</head>
<body>
</body>
</html>
由于应用依赖 Sencha Touch,我们还需要在 spec - runner.html 中添加相关代码:
<script type="text/javascript" src="../touch/sencha-touch-all.js"> </script>
- 定义辅助脚本 :在 helpers/SpecHelper.js 中定义辅助脚本,用于清除 Ext.data.Model 的缓存:
Ext.require('Ext.data.Model');
afterEach(function () {
Ext.data.Model.cache = {};
});
并在 spec - runner.html 中包含该脚本:
<script type="text/javascript" src="helpers/SpecHelper.js"> </script>
- 实现健全性测试 :在 spec/javascripts/sanitySpec.js 中实现一个简单的健全性测试:
describe("Sanity", function() {
it("succeeds", function() {
expect(true).toEqual(true);
});
});
并在 spec - runner.html 中包含该测试:
<script type="text/javascript" src="javascripts/sanitySpec.js"> </script>
3. 为控制器和模型编写 Jasmine 测试
3.1 为控制器编写测试
在编写实际测试之前,我们需要在 spec - runner.html 中包含控制器:
<script type="text/javascript" src="../app/controller/Main.js"> </script>
然后在 javascripts/controller/MainControllerSpec.js 中编写测试:
describe('Imaginary.controller.Main', function() {
var controller, app;
beforeEach(function() {
app = Ext.create('Ext.app.Application', {
name: 'Imaginary'
});
controller = Ext.create('Imaginary.controller.Main', {
application: app
});
controller.launch();
});
afterEach(function() {
app.destroy();
});
//...
});
对于 Main 控制器中的 getCameraPicture 方法,我们编写以下测试:
describe('#getCameraPicture', function() {
it('calls to get camera picture', function() {
spyOn(controller, 'getCameraPicture');
controller.getCameraPicture();
expect(controller.getCameraPicture).toHaveBeenCalled();
})
it('passes testing url to callback', function() {
controller.getCameraPicture(function(url) {
expect(url).toEqual('resources/images/test.jpg');
});
})
});
3.2 为模型编写测试
同样,我们需要在 spec - runner.html 中包含模型和测试文件:
<script type="text/javascript" src="../app/model/Picture.js"> </script>
<script type="text/javascript" src="javascripts/model/PictureModelSpec.js"></script>
在 javascripts/model/PictureModelSpec.js 中编写测试:
describe('Imaginary.model.Picture', function() {
it('exists', function() {
var model = Ext.create('Imaginary.model.Picture');
expect(model.$className).toEqual ('Imaginary.model.Picture');
});
it('has data', function() {
var model = Ext.create('Imaginary.model.Picture', {
id: 1,
url: 'some/test/url.jpg'
});
expect(model.get('id')).toEqual(1);
expect(model.get('url')).toEqual('some/test/url.jpg');
});
});
4. 使用 PhantomJS 运行测试
为了在无头浏览器中运行测试,我们可以使用 PhantomJS。首先,使用 npm 安装 grunt - contrib - jasmine:
$ npm install grunt-contrib-jasmine --save-dev
然后,在 spec 文件夹中添加配置好的 Gulpfile.js 文件:
module.exports = function(grunt) {
'use strict';
grunt.initConfig({
jasmine: {
src: '../app/**/*.js',
options: {
specs: 'javascripts/**/*Spec.js',
helpers: 'helpers/*Helper.js',
vendor: [
'../touch/sencha-touch-all.js'
]
}
}
});
grunt.loadNpmTasks('grunt-contrib-jasmine');
grunt.registerTask('test', ['jasmine']);
grunt.registerTask('default', ['test']);
};
最后,使用以下命令运行测试:
$ grunt
$ grunt test
这样,我们就可以在命令行中看到所有测试的运行结果。
5. 使用 DalekJS 在真实浏览器中测试
DalekJS 是一个不错的 Node.js 模块,它可以让我们在真实浏览器中运行测试。以下是使用步骤:
1.
安装 Dalek CLI
:
$ npm install -g dalek-cli
- 创建测试文件夹并配置 package.json :
{
"name": "DalekJS-Test",
"description": "DalekJS Test Description",
"version": "0.0.1",
"devDependencies": {
"dalekjs": "*",
"dalek-browser-chrome": "*"
}
}
- 编写测试代码 :
var url = 'http://localhost:1841/';
var title = 'DalekJS test';
module.exports = {
'should interact with the application': function (test) {
test
.open(url)
.assert.title().is('Imaginary')
.wait(500)
.assert.text('#takePhotoBtn', 'Take Photo', 'The title on the button "Take Photo"')
.click('#takePhotoBtn')
.wait(500)
.assert.text('#retakePhotoBtn', 'Retake', 'The title on the retake button "Retake"')
.assert.text('#savePhotoBtn', 'Save', 'The title on the save button "Save"')
.assert.text('#closePhotoBtn', 'Close', 'The title on the close button "Close"')
.done()
}
};
- 运行测试 :
$ dalek test.js -b chrome
如果测试失败,我们可以根据错误信息进行修改,例如将
#closePhotoBtn
改为
#cancelPhotoBtn
。
6. 使用 Appium 和 browser - perf 进行性能测试
在开发 PhoneGap/Cordova 应用时,性能是一个重要的挑战。我们可以使用 Appium 和 browser - perf 进行性能测试。
1.
安装工具
:
$ npm install -g browser-perf
$ npm install -g appium
- 编写配置文件 :在 ios - hybrid - appium.config.json 文件中插入以下代码:
{
"selenium": "http://localhost:4723/wd/hub",
"browsers": [{
"platformName": "iOS",
"platformVersion": "8.3",
"deviceName": "iPhone 6",
"app": "/Users/cybind/Projects/phonegap-by-example/imaginary/cordova/platforms/ios/build/emulator/Imaginary.app"
}]
}
- 运行测试 :
$ appium
$ browser-perf -c ios-hybrid-appium.config.json
这样,我们就可以在控制台看到性能测试结果。
7. 其他测试工具
除了上述工具,市场上还有许多其他的测试平台、工具和服务,以下是两个比较有趣的工具:
-
Telerik Test Studio
:可用于记录和自动化原生、Web 或混合 iOS 应用的 UI 测试。使用步骤如下:
1. 下载并安装测试工作室和移动测试 SDK。
2. 配置可测试的构建。
3. 将应用部署到设备。
4. 启动测试工作室并记录测试。
5. 访问记录的脚本并执行。
产品地址:http://www.telerik.com/mobile - testing
-
Sauce Labs
:提供自动化跨浏览器和移动测试,支持编写 Selenium 和 JavaScript 单元测试,并在云端的多个模拟器上运行。它基于 Appium,还支持手动测试多种移动设备和浏览器,并且与持续集成(CI)服务集成良好。
综上所述,通过合理使用这些测试方法和工具,我们可以全面地对移动应用进行测试,确保应用的质量和性能。无论是单元测试、集成测试,还是性能测试,都有相应的工具和方法可供选择。希望本文能为开发者在移动应用测试方面提供一些帮助。
移动应用测试全攻略:从单元到性能的实战指南
8. 测试工具对比分析
为了更清晰地了解各种测试工具的特点和适用场景,我们对上述介绍的测试工具进行对比分析,具体如下表所示:
| 测试工具 | 测试类型 | 特点 | 适用场景 |
|---|---|---|---|
| Jasmine | 单元测试、集成测试 | 简洁易用,提供丰富的断言方法;可与多种 JavaScript 项目集成 | 小型到中型 JavaScript 项目的单元和集成测试 |
| PhantomJS + grunt - contrib - jasmine | 无头浏览器测试 | 无需真实浏览器,可在命令行运行;适合自动化测试 | 持续集成环境下的自动化测试 |
| DalekJS | 真实浏览器测试 | 可控制真实浏览器进行测试;支持多种浏览器 | 需要模拟真实用户操作的测试场景 |
| Appium + browser - perf | 性能测试 | 可模拟用户交互,测量性能指标;支持 iOS 和 Android 应用 | PhoneGap/Cordova 应用的性能测试 |
| Telerik Test Studio | UI 测试 | 可记录和自动化 UI 测试;适用于多种应用类型 | 原生、Web 或混合 iOS 应用的 UI 测试 |
| Sauce Labs | 跨浏览器和移动测试 | 支持在云端多种模拟器上运行测试;支持手动测试 | 需要进行跨浏览器和移动设备测试的项目 |
通过这个表格,开发者可以根据项目的具体需求和特点,选择最合适的测试工具。
9. 测试流程优化建议
在实际的移动应用开发过程中,为了提高测试效率和质量,我们可以对测试流程进行优化。以下是一个优化后的测试流程 mermaid 流程图:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
A([开始]):::startend --> B(需求分析):::process
B --> C(测试计划制定):::process
C --> D(单元测试):::process
D --> E{单元测试通过?}:::decision
E -->|是| F(集成测试):::process
E -->|否| D
F --> G{集成测试通过?}:::decision
G -->|是| H(性能测试):::process
G -->|否| F
H --> I{性能测试通过?}:::decision
I -->|是| J(UI 测试):::process
I -->|否| H
J --> K{UI 测试通过?}:::decision
K -->|是| L(跨浏览器和移动测试):::process
K -->|否| J
L --> M{跨浏览器和移动测试通过?}:::decision
M -->|是| N([结束]):::startend
M -->|否| L
这个流程包含了从需求分析到最终测试完成的各个阶段,每个阶段都有明确的通过条件,确保只有通过前一个阶段的测试,才能进入下一个阶段。这样可以避免在后续测试中发现前期测试未解决的问题,提高测试效率。
10. 测试中的常见问题及解决方法
在使用上述测试工具和方法进行测试的过程中,可能会遇到一些常见问题,以下是一些问题及相应的解决方法:
-
测试环境配置问题
- 问题描述 :在安装和配置测试工具时,可能会遇到依赖冲突、版本不兼容等问题。
- 解决方法 :仔细阅读工具的官方文档,按照文档要求进行安装和配置。如果遇到依赖冲突,可以尝试使用虚拟环境或更新依赖版本。
-
测试用例执行失败
- 问题描述 :测试用例在执行过程中可能会因为各种原因失败,如代码逻辑错误、测试数据异常等。
- 解决方法 :首先检查测试用例的代码,确保其逻辑正确。然后检查测试数据是否符合预期,如果数据异常,需要对数据进行修正。
-
性能测试结果不准确
- 问题描述 :在进行性能测试时,可能会得到不准确的结果,如帧率测量异常、响应时间过长等。
- 解决方法 :检查测试环境是否稳定,确保测试过程中没有其他干扰因素。同时,检查配置文件是否正确,参数设置是否合理。
11. 总结与展望
本文详细介绍了多种移动应用测试方法和工具,包括 Jasmine 集成测试、使用 PhantomJS 进行无头浏览器测试、使用 DalekJS 进行真实浏览器测试、使用 Appium 和 browser - perf 进行性能测试,以及其他一些测试工具。通过合理使用这些工具和方法,开发者可以全面地对移动应用进行测试,确保应用的质量和性能。
随着移动应用技术的不断发展,测试领域也在不断创新。未来,我们可以期待更智能化、自动化的测试工具出现,能够更高效地发现应用中的问题。同时,测试与开发的融合将更加紧密,实现持续测试和持续集成,进一步提高软件开发的效率和质量。
希望本文能为开发者在移动应用测试方面提供有价值的参考,帮助他们更好地应对测试挑战,开发出高质量的移动应用。
超级会员免费看
1022

被折叠的 条评论
为什么被折叠?



