zoukankan      html  css  js  c++  java
  • Elixir 单元测试

    概述

    elixir 中自带了单元测试框架 ExUnit ,其中提供单元测试的一系列,主要包含以下模块:

    1. ExUnit: 单元测试框架
    2. ExUnit.Assertions: 断言
    3. ExUnit.Case: 测试用例
    4. ExUnit.DocTest: 在注释写测试用例,类似 python 的 doctest
    5. ExUnit.Callbacks: 单元测试中回调
    6. ExUnit.CaseTemplate: 测试用例模板,用在有大量同类测试的场景
    7. ExUnit.Test: 单元测试信息,用于描述单元测试本身,相当于单元测试的元数据
    8. ExUnit.TestCase: 测试用例信息,用于描述单元测试用例本身,相当于测试用例的元数据
    9. ExUnit.CaptureIO 和 ExUnit.CaptureLog: 辅助测试时获取 IO 和 log 的输出
    10. ExUnit.Formatter: 格式化测试输出的信息
    11. 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 中的还有些模块没有尝试,以后在实际用到时再写相应的心得。

  • 相关阅读:
    笨方法学python中执行argv提示ValueError: not enough values to unpack (expected 4, got 1)
    VMware workstation安装
    Redis bigkey分析
    MySQL drop table 影响及过程
    MySQL 大表硬连接删除
    ES elasticsearch 各种查询
    ES elasticsearch 各种聚合
    ES elasticsearch 聚合统计
    ES elasticsearch 实现 count单字段,分组取前多少位,以地理位置中心进行统计
    MySQL行溢出、varchar最多能存多少字符
  • 原文地址:https://www.cnblogs.com/wang_yb/p/6357545.html
Copyright © 2011-2022 走看看