何时进行单元测试?

时间:2016-03-26 10:39:21

标签: unit-testing junit build continuous-integration

我们目前正在自动化的持续集成环境中设置构建过程,并面临基本问题,何时运行单元测试?

一种方法是使用每个构建任务运行单元测试。因此,只要一个单元测试失败,整个构建就会失败。这样做的好处是,开发人员总是被迫将单元测试保持为绿色,因为他/她无法运行应用程序。另一方面,在开发过程中通过修复测试总是分散注意力 - 这可能会迫使您在非常小的迭代中工作。除此之外,运行应用程序的时间总是增加,因为每次都必须等待测试。

另一种方法是让CI-Server在每次新提交后运行测试并让开发人员知道出现问题。通过这种方式,开发人员可以非常自由,在什么时候关心单元测试,但同一分支上的其他开发人员可能会受到影响,因为他们无法确定软件的所有部分是否按预期工作并且必须检查他们自己,如果失败的测试也可能影响他们的工作。

您是否有任何最佳实践或建议,这是运行测试的好时机?

BTW:当然,我们还运行更大的集成测试,这些测试是在单独的CI过程中处理的。

2 个答案:

答案 0 :(得分:0)

您的构建过程应该有两个目标:构建和测试。不指定任何其他内容时,test应该是默认目标。测试无法运行直到项目构建,因此构建目标是测试的依赖性。所以(假设使用make):makemake test将构建并测试。 make build将构建项目。

现在,如果您正在使用某些IDE,您可以考虑以某种单独的方式进行测试"在"之外的IDE。所以,也许可以添加第三个目标ide并让ide构建那个目标。然后它可以将构建目标作为正常依赖项,并且最后一步在后台生成一个新作业以在其自己的终端窗口中进行测试,类似于(在linux下):( xterm -e ./run-tests &)。

如果你在一个ide之外开发(就像我一样),那么只需要一个单独的终端来运行build&测试。一旦测试开始,你就知道构建过程已经完成,所以即使你的测试仍在运行,你也可以运行你的应用程序。

为了证明这一点(并作为在后台运行测试的概念证明)我刚刚创建了一些简单的测试用例:

bodo.c:

#include <stdio.h>

int main(int argc, char * argv[]) {
        printf("Hallo %s", argc > 1 ? argv[1] : "Welt");
        return 0;
}

生成文件:

test: build run-tests

ide: build run-tests-background

run-tests-background:
        ( xterm -e ./run-tests --wait & )

run-tests:
        ./run-tests

build: bodo

bodo: bodo.o

bodo.o: bodo.c

.PHONY: run-tests run-tests-background

运行测试:

#! /bin/sh

retval=true
if test "$(./bodo)" != "Hallo Welt"
then
        echo "Test failed []"
        retval=false
fi
if test "$(./bodo Bodo)" != "Hallo Bodo"
then
        echo "Test failed [Bodo]"
        retval=false
fi
if test "$(./bodo Fail)" != "Hallo Bodo"
then
        echo "Test failed [Fail]"
        retval=false
fi
sleep 5 # Simulate some more tests
if $retval
then
        echo "All tests suceeded ;)"
else
        echo "Some tests failed :("
fi
if test "$1" == "--wait"
then
        read -p "Press ENTER to close" enter
fi
if $retval
then
        exit 0
else
        exit 2
fi

用法:

构建项目但不运行测试

make build

构建项目并在当前终端中运行测试

make

构建项目并在单独的终端中运行测试。一旦构建过程完成并且测试开始,Make将返回

make ide

两个助手,不应该手工操作: 仅在当前终端中运行测试(如果项目尚未构建,则会失败)

make run-tests

仅在单独的终端中运行测试(如果项目尚未构建,则会失败)。 Make会立即返回

make run-tests-background

答案 1 :(得分:0)

简短回答:在每个分支上的每次提交的构建服务器上运行所有单元测试。假设您的单元测试运行时间不长,那么确实没有任何缺点。至于在本地运行每个构建任务的所有单元测试,这将是一种矫枉过正。开发人员应该有纪律来决定何时运行测试以及何时不运行。

如果出现问题,您希望尽快知道,以便及时修复。您还想知道所有失败的测试,而不仅仅是第一次失败的测试。当存在多个问题时,仅修复一个问题然后必须提交,推送并等待构建再次运行以查看是否存在更多问题将是一个非常恼人的工作流。