Skip to content

单元测试代码

单元测试

单元测试编写

Python 代码中使用 pytest 测试类组织测试用例,Java 代码中使用 JUnit5 测试框架进行测试用例的编写。 在测试类中编写具体的测试方法,每一个测试方法是一个测试用例。

测试用例编写

  • 根据需求编写计算器加法相应的测试用例
  • 在调用每个测试方法之前打印【开始计算】
  • 在调用测试方法之后打印【结束计算】
  • 调用完所有的测试用例最终输出【结束测试】
  • 为用例添加标签
  • 用例中要添加断言,验证结果
  • 灵活使用测试装置

Python 示例代码

import allure
import pytest
from Cal.Calculator import Calculator
from utils.log_utils import logger

'''
创建测试用例,传入三组参数,每组两个元素,判断每组参数里面表达式和值是否相等。
'''

class TestAdd:
    # 实例化一个Calculator()实例
    calc = Calculator()

    def setup(self):
        print("开始计算")

    def teardown(self):
        print("结束计算")

    def test_add_001(self, 1, 1):
        result = self.calc.add(x, y)
        logger.info(f"2个整数相加的结果为{result}")
        assert result == 2

Java 示例代码

//创建测试用例,传入三组参数,每组两个元素,判断每组参数里面表达式和值是否相等。
public class CalculatorTest {
    //实例化对象:Calculator类
    Calculator calculator = new Calculator();

    @BeforeEach
    void setUp() {
        System.out.println("开始计算");
    }

    @Test
    public void add01() {
        int result = calculator.add(3, 5);
        System.out.println("2个整数相加的结果为: " + result);
        assertEquals(8,result);

    }

    @AfterEach
    void tearDown() {
        System.out.println("结束计算");

    }
}

添加日志

在测试用例中添加日志

Python 示例代码

logger.info(f"2个整数相加的结果为{result}")

Java 示例代码

static final Logger logger = getLogger(lookup().lookupClass());

logger.info("2个整数相加的结果为:{} ",result);

参数化

如果多个测试用例,测试步骤完全相同,只有测试数据不同,可以使用参数化的方式,在一个测试方法中完成多个测试用例的执行。

Python 示例代码

@pytest.mark.parametrize("x,y,excepted", [[1, 1, 2]],ids=["两个整数相加"])
def test_add_001(self, x, y, excepted):
    result = self.calc.add(x, y)
    logger.info(f"2个整数相加的结果为{result}")
    assert result == excepted

Java 示例代码

    @ParameterizedTest
    @ValueSource
    public void add01(int x, int y, int excepted) {
        int result = calculator.add(x, y);
        logger.info("2个整数相加的结果为:{} ",result);
        assertEquals(excepted,result);
    }
    static Stream<Arguments> add01(){
        return Stream.of(
                Arguments.arguments(2,2,4),
                Arguments.arguments(4,5,9),
                Arguments.arguments(8,3,11)
        );
    }

设置测试用例优先级

设置测试用例的优先级可以方便单独执行其中一种优先级的测试用例。

Python 示例代码

使用 pytest 添加标签的特性,在 pytest.ini 文件中声明用例优先级。

[pytest]
markers = addP0
        addP1
        addP2

在测试用例中添加优先级

@pytest.mark.P0
def test_add_001(self, x, y, excepted):
    ...

Java示例代码

@ParameterizedTest
@ValueSource
@Order(6)
public void add01(int x, int y, int excepted) {
    ...
}

添加测试报告

使用 allure,在测试用例的不同位置添加测试报告信息。

Python 示例代码

@allure.epic("计算器")
@allure.feature("计算器加法功能")
class TestAdd:
    ...

Java 示例代码

@Epic("计算器")
@Feature("计算器加法功能")
public class CalculatorTest {
    ...
}

加法测试用例示例代码

Python 用例代码

import allure
import pytest
from Cal.Calculator import Calculator
from utils.log_utils import logger

'''
创建测试用例,传入三组参数,每组两个元素,判断每组参数里面表达式和值是否相等。
'''

@allure.epic("计算器")
@allure.feature("计算器加法功能")
class TestAdd:
    # 实例化一个Calculator()实例
    calc = Calculator()

    def setup(self):
        print("开始计算")

    def teardown(self):
        print("结束计算")

    def teardown_class(self):
        print("结束测试")

    @allure.title("【正向】2个整数相加,结果计算正确")
    @pytest.mark.addP0
    @pytest.mark.parametrize("x,y,excepted", [[1, 1, 2]],ids=["两个整数相加"])
    def test_add_001(self, x, y, excepted):
        result = self.calc.add(x, y)
        logger.info(f"2个整数相加的结果为{result}")
        assert result == excepted

    @allure.title("【正向】2个浮点数相加,结果计算正确")
    @pytest.mark.addP0
    @pytest.mark.parametrize("x,y,excepted", [[1, 1, 2]], ids=["两个浮点数相加"])
    def test_add_002(self, x, y, excepted):
        result = self.calc.add(x, y)
        logger.info(f"2个浮点数相加结果为{result}")
        assert result == excepted

    @allure.title("【正向】整数与浮点数相加,结果计算正确")
    @pytest.mark.addP0
    @pytest.mark.parametrize("x,y,excepted", [[1, 1, 2]], ids=["整数与浮点数相加"])
    def test_add_003(self, x, y, excepted):
        result = self.calc.add(x, y)
        logger.info(f"整数与浮点数相加的结果为{result}")
        assert result == excepted

    @allure.title("【边界】有效边界值相加,结果计算正确")
    @pytest.mark.addP1
    @pytest.mark.parametrize("x,y,excepted", [[98.99, 99, 197.99], [99, 98.99, 0197.99], [-98.99, -99, -197.99],
                                              [-99, -98.99, -197.99]])
    def test_add_004(self, x, y, excepted):
        result = self.calc.add(x, y)
        logger.info(f"有效边界值相加的结果为{result}")
        assert result == excepted

    @allure.title("【边界】无效边界值相加,给出提示信息")
    @pytest.mark.addP1
    @pytest.mark.parametrize("x,y,excepted", [[99.01, 0, "参数x大小超出最大范围"], [-99.01, -1, "参数x大小超出最小范围"],
                                              [2, 99.01, "参数y大小超出最大范围"], [1, -99.01, "参数y大小超出最小范围"]],
                             ids=["参数x大小超出最大范围","参数x大小超出最小范围","参数y大小超出最大范围","参数y大小超出最小范围"])
    def test_add_005(self, x, y, excepted):
        result = self.calc.add(x, y)
        logger.info(f"无效边界值相加的结果为{result}")
        assert result == excepted

    @allure.title("【类型】输入中文,给出提示信息")
    @pytest.mark.addP1
    @pytest.mark.parametrize("x,y,excepted", [["文", 9.3, "x为中文字符"], [4, "字", "y为中文字符"]],
                             ids=["x为中文字符","y为中文字符"])
    def test_add_006(self, x, y, excepted):
        try:
            result = self.calc.add(x, y)
        except TypeError as e:
            logger.info(f"类型错误{e}")

    @allure.title("【类型】输入英文,给出提示信息")
    @pytest.mark.addP1
    @pytest.mark.parametrize("x,y,excepted", [["nu", 0.2, "x为英文字符"], [30, "t", "y为英文字符"]],
                             ids=["x为英文字符","x为英文字符"])
    def test_add_007(self, x, y, excepted):
        try:
            result = self.calc.add(x, y)
        except TypeError as e:
            logger.info(f"类型错误{e}")

    @allure.title("【类型】输入特殊字符,给出提示信息")
    @pytest.mark.addP1
    @pytest.mark.parametrize("x,y,excepted", [["*&", 0.2, "x为特殊字符"], [21.45, "@", "y为特殊字符"]],
                             ids=["x为英文字符", "x为英文字符"])
    def test_add_008(self, x, y, excepted):
        try:
            result = self.calc.add(x, y)
        except TypeError as e:
            logger.info(f"类型错误{e}")

    @allure.title("【类型】输入为空,给出提示信息")
    @pytest.mark.addP2
    @pytest.mark.parametrize("x,y,excepted", [["", 20.93, "x为空"], [-3, "", "y为空"]],
                             ids=["x为空", "y为空"])
    def test_add_009(self, x, y, excepted):
        try:
            result = self.calc.add(x, y)
        except TypeError as e:
            logger.info(f"类型错误{e}")

    @allure.title("【类型】输入空格,给出提示信")
    @pytest.mark.addP2
    @pytest.mark.parametrize("x,y,excepted", [["", 3.14, "x为空格"], [-90, "", "y为空格"]],
                             ids=["x为空格", "y为空格"])
    def test_add_010(self, x, y, excepted):
        try:
            result = self.calc.add(x, y)
        except TypeError as e:
            logger.info(f"类型错误{e}")

完整的自动化测试用例代码请查看源码:pytest 计算器测试代码

Java 用例代码

package com.ceshiren;

import io.qameta.allure.Epic;
import io.qameta.allure.Feature;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.slf4j.Logger;

import java.util.Objects;
import java.util.stream.Stream;

import static java.lang.invoke.MethodHandles.lookup;
import static org.junit.jupiter.api.Assertions.*;
import static org.slf4j.LoggerFactory.getLogger;

//创建测试用例,传入三组参数,每组两个元素,判断每组参数里面表达式和值是否相等。
@Epic("计算器")
@Feature("计算器加法功能")
public class CalculatorTest {
    //获得具有所需名称的记录器
    static final Logger logger = getLogger(lookup().lookupClass());
    //实例化对象:Calculator类
    Calculator calculator = new Calculator();

    @BeforeEach
    void setUp() {
        logger.info("开始计算");
    }

    @DisplayName("【正向】2个整数相加,结果计算正确")
    @ParameterizedTest
    @MethodSource
    @Tag("addP0")
    public void add01(int x, int y, int excepted) {
        int result = calculator.add(x, y);
        logger.info("2个整数相加的结果为:{} ",result);
        assertEquals(excepted,result);
    }
    static Stream<Arguments> add01(){
        return Stream.of(
                Arguments.arguments(2,2,4),
                Arguments.arguments(4,5,9),
                Arguments.arguments(8,3,11)
        );
    }

    @DisplayName("【正向】2个浮点数相加,结果计算正确")
    @ParameterizedTest
    @MethodSource
    @Tag("addP0")
    public void add02(double x, double y, double excepted) {
        double result = calculator.add(x, y);
        logger.info("2个浮点数相加的结果为:{} ",result);
        assertEquals(excepted,result);
    }
    static Stream<Arguments> add02(){
        return Stream.of(
                Arguments.arguments(2.1,2.2,4.3),
                Arguments.arguments(4.7,5.4,10.1),
                Arguments.arguments(8.6,3.8,12.4)
        );
    }

    @DisplayName("【正向】整数与浮点数相加,结果计算正确")
    @ParameterizedTest
    @MethodSource
    @Tag("addP0")
    public void add03(int x, double y, double excepted) {
        double result = calculator.add(x, y);
        logger.info("整数与浮点数相加的结果为:{} ",result);
        assertEquals(excepted,result);
    }
    static Stream<Arguments> add03(){
        return Stream.of(
                Arguments.arguments(2,2.2,4.2),
                Arguments.arguments(4,5.4,9.4),
                Arguments.arguments(8,3.8,11.8)
        );
    }

    @DisplayName("【边界】有效边界值相加,结果计算正确")
    @ParameterizedTest
    @MethodSource
    @Tag("addP1")
    public void add04(double x, double y, double excepted) {
        double result = calculator.add(x, y);
        logger.info("有效边界值相加的结果为:{} ",result);
        assertEquals(excepted,result);
    }
    static Stream<Arguments> add04(){
        return Stream.of(
                Arguments.arguments(98.99,99,197.99),
                Arguments.arguments(99,98.99,197.99),
                Arguments.arguments(-98.99,-99,-197.99)
        );
    }
    @DisplayName("【边界】无效边界值相加,给出提示信息")
    @ParameterizedTest
    @MethodSource
    @Tag("addP1")
    public void add05(double x, double y, double excepted) {
        double result = calculator.add(x, y);
        logger.info("无效边界值相加的结果为:{} ",result);
        assertEquals(excepted,result);
    }
    static Stream<Arguments> add05(){
        return Stream.of(
                Arguments.arguments(99.01, 0, "请输入范围内的整数"),
                Arguments.arguments(-99.01, -1,"请输入范围内的整数"),
                Arguments.arguments(2, 99.01,"请输入范围内的整数"),
                Arguments.arguments(1, -99.01,"请输入范围内的整数")
        );
    }



    @AfterEach
    void tearDown() {
        logger.info("结束计算");
    }

    @AfterAll
    static void afterAll() {
        logger.info("结束测试");
    }
}

完整的自动化测试用例代码请查看源码:JUnit 计算器测试代码