单元测试介绍
我们如何保证 app 在增加了新特性或者改变了现有功能之后还能正常工作呢?答案是写测试!
How can you ensure that your app continues to work as you add more features or change existing functionality? By writing tests.
使用单元测试可轻松地验证单个函数、方法或类的行为。
test
这个 package 提供了写单测的核心框架,
flutter_test
package 则提供了额外的功能来测试 widget。
Unit tests are handy for verifying the behavior of a single function,
method, or class. The test
package provides the
core framework for writing unit tests, and the flutter_test
package provides additional utilities for testing widgets.
本教程将会为大家演示 test
package 的用法,内容如下:
This recipe demonstrates the core features provided by the test
package
using the following steps:
-
将
test
或者flutter_test
加入依赖;Add the
test
orflutter_test
dependency. -
创建测试文件;
Create a test file.
-
创建一个要测试的类;
Create a class to test.
-
为创建的类写一个测试;
Write a
test
for our class. -
整合多个测试到一个
group
;Combine multiple tests in a
group
. -
执行测试。
Run the tests.
关于 package 测试的更多内容,可移步至 test package 的文档。
For more information about the test package, see the test package documentation.
test
或者 flutter_test
加入依赖文件
1. 添加测试依赖 —— 将
test
or flutter_test
dependency
1. Add the 如果 Dart package 没有依赖 Flutter,可以导入 test
package。
Test package 提供了编写测试所需要的核心功能。当我们写的 package 需要被 web、服务端和 Flutter app 使用时,这是最佳的方式。
The test
package provides the core functionality for
writing tests in Dart. This is the best approach when
writing packages consumed by web, server, and Flutter apps.
dev_dependencies:
test: <latest_version>
2. 创建测试文件
2. Create a test file
本例中,我们会创建两个文件:counter.dart
和 counter_test.dart
。
In this example, create two files: counter.dart
and counter_test.dart
.
counter.dart
文件包含一个位于 lib
文件夹的待测试类,而位于 test
文件夹的 counter_test.dart
文件将包含测试本身。
The counter.dart
file contains a class that you want to test and
resides in the lib
folder. The counter_test.dart
file contains
the tests themselves and lives inside the test
folder.
通常测试文件应位于放置在 Flutter 应用或包的根目录下的 test
文件夹。测试文件通常以 _test.dart
命名,这是 test runner 寻找测试文件的惯例。
In general, test files should reside inside a test
folder
located at the root of your Flutter application or package.
Test files should always end with _test.dart
,
this is the convention used by the test runner when searching for tests.
创建完成后,文件目录结构如下:
When you’re finished, the folder structure should look like this:
counter_app/
lib/
counter.dart
test/
counter_test.dart
3. 创建一个要测试的类
3. Create a class to test
下一步,我们需要一个「单元」来测试。记住:「单元」是一个抽象的名称,它可以表示一个函数、方法或者类。本例中,我们会在 lib/counter.dart
文件中创建一个 Counter
类。它负责增加或减少一个从 0
开始的 value
。
Next, you need a “unit” to test. Remember: “unit” is another name for a
function, method, or class. For this example, create a Counter
class
inside the lib/counter.dart
file. It is responsible for incrementing
and decrementing a value
starting at 0
.
class Counter { int value = 0; void increment() => value++; void decrement() => value--; }
注意: 为了简化内容,本教程没有遵守「测试驱动开发」的写法。如果你擅长那种开发模式,当然可以选择用那种方式来写。
Note: For simplicity, this tutorial does not follow the “Test Driven Development” approach. If you’re more comfortable with that style of development, you can always go that route.
4. 为创建的类写一个测试
4. Write a test for our class
我们将在 counter_test.dart
文件中写第一个测试。使用顶级函数 test
来定义,可通过执行顶级函数 expect
来检查结果正确与否。这两个函数都来自 test
这个 package。
Inside the counter_test.dart
file, write the first unit test. Tests are
defined using the top-level test
function, and you can check if the results
are correct by using the top-level expect
function.
Both of these functions come from the test
package.
// Import the test package and Counter class import 'package:test/test.dart'; import 'package:counter_app/counter.dart'; void main() { test('Counter value should be incremented', () { final counter = Counter(); counter.increment(); expect(counter.value, 1); }); }
group
5. 整合多个测试到一个
group
5. Combine multiple tests in a 如果多个测试之间互相关联,可以使用 test
这个 package 提供的 group
函数将他们整合到一起。
If you have several tests that are related to one another,
combine them using the group
function provided by the test
package.
import 'package:test/test.dart'; import 'package:counter_app/counter.dart'; void main() { group('Counter', () { test('value should start at 0', () { expect(Counter().value, 0); }); test('value should be incremented', () { final counter = Counter(); counter.increment(); expect(counter.value, 1); }); test('value should be decremented', () { final counter = Counter(); counter.decrement(); expect(counter.value, -1); }); }); }
6. 执行测试
6. Run the tests
现在 Counter
类和它的测试都有了,开始执行测试!
Now that you have a Counter
class with tests in place,
you can run the tests.
用 IntelliJ 或 VSCode 执行测试
Run tests using IntelliJ or VSCode
IntelliJ 和 VSCode 的 Flutter 插件支持执行测试。用这种方式执行测试是最好的,因为它可以提供最快的反馈闭环,而且还支持断点调试。
The Flutter plugins for IntelliJ and VSCode support running tests. This is often the best option while writing tests because it provides the fastest feedback loop as well as the ability to set breakpoints.
-
IntelliJ
-
打开文件
counter_test.dart
Open the
counter_test.dart
file -
选择菜单
Run
Select the
Run
menu -
点击选项
Run 'tests in counter_test.dart'
Click the
Run 'tests in counter_test.dart'
option -
或者,也可以使用系统快捷键!
Alternatively, use the appropriate keyboard shortcut for your platform.
-
-
VSCode
-
打开文件
counter_test.dart
Open the
counter_test.dart
file -
在菜单里选择
Run
Select the
Run
menu -
点击选项
Start Debugging
Click the
Start Debugging
option -
或者,也可以使用系统快捷键!
Alternatively, use the appropriate keyboard shortcut for your platform.
-
在终端执行测试
Run tests in a terminal
我们也可以打开终端,在工程根目录输入以下命令来执行测试:
You can also use a terminal to run the tests by executing the following command from the root of the project:
flutter test test/counter_test.dart
你可以执行下面的命令获得更多有关单元测试的帮助:
For more options regarding unit tests, you can execute this command:
flutter test --help