Elixir 单元测试
概述
elixir 中自带了单元测试框架 ExUnit ,其中提供单元测试的一系列,主要包含以下模块:
- ExUnit: 单元测试框架
- ExUnit.Assertions: 断言
- ExUnit.Case: 测试用例
- ExUnit.DocTest: 在注释写测试用例,类似 python 的 doctest
- ExUnit.Callbacks: 单元测试中回调
- ExUnit.CaseTemplate: 测试用例模板,用在有大量同类测试的场景
- ExUnit.Test: 单元测试信息,用于描述单元测试本身,相当于单元测试的元数据
- ExUnit.TestCase: 测试用例信息,用于描述单元测试用例本身,相当于测试用例的元数据
- ExUnit.CaptureIO 和 ExUnit.CaptureLog: 辅助测试时获取 IO 和 log 的输出
- ExUnit.Formatter: 格式化测试输出的信息
- ExUnit.Filters: 控制测试用例的过滤
一般主要使用的模块是 ExUnit.Assertions,ExUnit.Case,ExUnit.DocTest
单元测试
下面通过各种测试用例的场景,来实际应用上面提到的各个模块。
构造一个测试场景
为了简单,假定测试的对象是一个计算器,包含基本的加减乘除运算。 创建工程,然后添加 加减乘除 四个方法:
$ mix new calc
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/calc.ex
* creating test
* creating test/test_helper.exs
* creating test/calc_test.exs
Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:
cd calc
mix test
Run "mix help" for more commands.
工程自动生成的代码 lib/calc.ex 中带有一个示例函数 hello
defmodule Calc do
@moduledoc """
Documentation for Calc.
"""
@doc """
Hello world.
## Examples
iex> Calc.hello
:world
"""
def hello do
:world
end
end
上面的 ##Examples 下的就是 doctest
然后,在上面的 Calc module 中增加4个简单的带测试函数:
def add(x, y) do
x+y
end
def minus(x, y) do
x-y
end
def mul(x, y) do
x*y
end
def division(x, y) do
div x, y
end
添加测试case (test/calc_test.exs)
针对上面4个方法,各写几个测试 case 如下:
defmodule CalcTest do
use ExUnit.Case
test "add method test" do
assert Calc.add(3, 3) == 6
end
test "add method test 2" do
refute Calc.add(3, 3) == 5
end
test "minus method test" do
assert Calc.minus(3, 3) == 0
end
test "multiply method test" do
assert Calc.mul(3, 3) == 9
end
test "division method test" do
assert Calc.division(3, 3) == 1
end
end
其中,test 方法来自于模块 ExUnit.Case, assert,refute 等来自于 ExUnit.Assertions 模块。 其他 assertion 参考: https://hexdocs.pm/ex_unit/ExUnit.Assertions.html
设置统一的测试参数
上面的测试是最基本的示例,上面的测试用例中每个用例的参数都是 (3,3),可以用 setup 方法统一设置每个case的相同参数。
defmodule CalcTest do
use ExUnit.Case, async: true
setup do
{:ok, [x: 3, y: 3]}
end
test "add method test", context do
assert Calc.add(context[:x], context[:y]) == 6
end
test "add method test 2", context do
refute Calc.add(context[:x], context[:y]) == 5
end
test "minus method test", context do
assert Calc.minus(context[:x], context[:y]) == 0
end
test "multiply method test", context do
assert Calc.mul(context[:x], context[:y]) == 9
end
test "division method test", context do
assert Calc.division(context[:x], context[:y]) == 1
end
end
除了 setup,还有 setup_all 方法也可以设置每个 case 的共通参数。 不同之处在于 setup 每个 test 执行之前都会运行。
测试中的回调
测试回调除了上面的 setup 和 setup_all 之外,还有一个 on_exit 回调,在每次测试case执行完之后运行。 以上回调属于 ExUnit.Callbacks 模块。
上面的setup中加入 on_exit 的回调:
setup context do
on_exit fn ->
IO.puts "#{context[:test]} finished!"
end
{:ok, [x: 3, y: 3]}
end
context[:test] 中是每个 test 后跟的字符串。 修改后执行结果如下:
$ mix test
test multiply method test finished!
.test add method test 2 finished!
.test add method test finished!
.test division method test finished!
.test minus method test finished!
.
Finished in 0.04 seconds
5 tests, 0 failures
Randomized with seed 604679
总结
elixir 中自带了完善的单元测试库,但是没有 mock 库,因为 elixir 社区不推荐使用 mock, 社区认为如果代码遵循良好的设计规范,就会很容易测试。
此外,ExUnit 中的还有些模块没有尝试,以后在实际用到时再写相应的心得。
Elixir 单元测试的更多相关文章
- 关于Elixir游戏服设计系列
写着写着就废球了,感觉空对空,实在没什么意思. 另外很快就要搞新项目,决定新项目就直接上elixir了.目前该做的准备工作已经探索了一些了. 以下的东西是写给同事参考的,感兴趣的可以看看,提建议更好. ...
- elixir mix 简介
概述 mix 是 elixir 工程的构建工具,利用 mix,可以快速方便的创建 elixir 工程,写单元测试,管理 elixir 包的依赖管理等等. 我觉得刚开始学习 elixir 的时候,先简单 ...
- elixir mix开发入门
备注: 简单使用mix 进行项目的生成,同时添加docker 构建支持 1. 生成项目 mix new mydemoproject 输出信息如下: * creating README.md * cre ...
- Intellij idea添加单元测试工具
1.idea 版本是14.0.0 ,默认带有Junit,但是不能自动生成单元测试,需要下载JunitGererator2.0插件 2.Settings -Plugins,下载 JunitGenerat ...
- Python的单元测试(二)
title: Python的单元测试(二) date: 2015-03-04 19:08:20 categories: Python tags: [Python,单元测试] --- 在Python的单 ...
- Python的单元测试(一)
title: Python的单元测试(一) author: 青南 date: 2015-02-27 22:50:47 categories: Python tags: [Python,单元测试] -- ...
- javascript单元测试框架mochajs详解
关于单元测试的想法 对于一些比较重要的项目,每次更新代码之后总是要自己测好久,担心一旦上线出了问题影响的服务太多,此时就希望能有一个比较规范的测试流程.在github上看到牛逼的javascript开 ...
- 使用NUnit为游戏项目编写高质量单元测试的思考
0x00 单元测试Pro & Con 最近尝试在我参与的游戏项目中引入TDD(测试驱动开发)的开发模式,因此单元测试便变得十分必要.这篇博客就来聊一聊这段时间的感悟和想法.由于游戏开发和传统软 ...
- 我这么玩Web Api(二):数据验证,全局数据验证与单元测试
目录 一.模型状态 - ModelState 二.数据注解 - Data Annotations 三.自定义数据注解 四.全局数据验证 五.单元测试 一.模型状态 - ModelState 我理解 ...
随机推荐
- Python中的序列操作
官方手册:https://docs.python.org/3.7/library/stdtypes.html#sequence-types-list-tuple-range 序列简介 序列是指按照位置 ...
- ABP适配Oracle全过程
一.背景 ABP的各类文档在网络上已经非常完善了,唯独缺少与oralce相关的资料,ABP官网也未给出一个较好的Oracle解决方案.正好最近在学习ABP相关知识,对ABP源码结构稍算熟悉,花了些 ...
- 开发谷歌浏览器插件会上瘾,搞了一个JSONViewer,一个页面格式化多条JSON,提升工作效率
最近写了一个谷歌浏览器插件(Chrome extension),拿出来分享下,希望能提升大家的工作效率. 一.背景 先说痛点:日常开发中,经常需要不停的把接口输出的JSON拷贝到在线JSON格式化页面 ...
- spring-framework-中文文档三:依赖注入DI
5.4依赖性 典型的企业应用程序不包含单个对象(或Spring的说法中的bean).即使最简单的应用程序也有几个对象一起工作来展示最终用户将其视为一个连贯的应用程序.下一节将介绍如何从定义许多独立的b ...
- 反向ajax实现原理
留言板显示留言一直刷新,那么实现原理是怎么样的? 一般发送留言就是通过正常的ajax向服务器发送数据,而实时显示留言就需要用到轮询了. 什么是轮询:就是使用定时器,每隔固定的时间从客户端向服务器发起请 ...
- 魔幻般冒泡背景的CSS3按钮动画
这是一款非常有特点的CSS3按钮,按钮的背景不是北京图片,也不是单纯的颜色,而是一组魔幻般的冒泡背景动画.当我们将鼠标滑过按钮时,按钮的冒泡背景动画就可以展示出来.可以说这款CSS3按钮的设计风格相当 ...
- #WEB安全基础 : HTML/CSS | 0x4HTML模块化
想让你的网页变得整洁吗?找我就对了,当然你会认识几个新元素,和它们交朋友吧! 我帮你联系一下这几个新元素,这样交朋友就变得简单了 images里放着图片 以下是index.html的代码 < ...
- angular ng-file-upload
传送门:https://github.com/danialfarid/ng-file-upload#install <script src="angular(.min).js" ...
- loj#6030. 「雅礼集训 2017 Day1」矩阵(贪心 构造)
题意 链接 Sol 自己都不知道自己怎么做出来的系列 不难观察出几个性质: 最优策略一定是先把某一行弄黑,然后再用这一行去覆盖不是全黑的列 无解当且仅当无黑色.否则第一个黑色所在的行\(i\)可以先把 ...
- Django引入静态文件
在HTML文件中引入方式: 简单引入一个bootstrap中的内敛表单,效果图如下: