首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为单元测试提供命令行参数是错误的做法吗?

为单元测试提供命令行参数是错误的做法吗?
EN

Software Engineering用户
提问于 2017-07-11 18:52:36
回答 5查看 3.9K关注 0票数 4

我在C++上,使用gtest作为主要框架。假设我有一个要测试的边缘检测函数,它以图像为输入并返回检测到的边缘图像。我有三个图像准备检查。

用一种自我包含的方式写它是不是更好呢?

代码语言:javascript
复制
void EdgeCheck(const std::string& input, const std::string& ans) {
    cv::Mat in_img = cv::imread(input);
    cv::Mat ans_img = cv::imread(ans);
    // Do some checks here
}

TEST(Edge) {
    EdgeCheck(std::string("path to image 1"),std::string("path to ans image 1"));
    EdgeCheck(std::string("path to image 2"),std::string("path to ans image 2"));
    EdgeCheck(std::string("path to image 3"),std::string("path to ans image 3"));
}

int main(int argc, char** argv) {
    return UnitTest::RunAllTests();
}

因此,这个测试可以通过简单的./unit-test执行,还是编写它更好呢?

代码语言:javascript
复制
TEST(Edge) {
    cv::Mat in_img = cv::imread(argv[1]);
    cv::Mat ans_img = cv::imread(argv[2]);

    // Do some check here
}

int main(int argc, char** argv) {
    return UnitTest::RunAllTests();
}

但它必须由

代码语言:javascript
复制
./unit-test image1 ans_image1
./unit-test image2 ans_image2
./unit-test image3 ans_image3

据我理解,根据UnitTest++命令行参数,第一种方法的优点是“编写良好的单元测试是独立的,而参数化测试意味着测试不再仅仅是测试,它现在是一个函数,而不是单元测试。”

但是,第二种方法的优点是它更灵活,因为如果我想添加image4和image5,我不需要重新编译代码,它可以在bash脚本上完成,但是这样可以使测试不自成体系。

哪种方法被认为是更好的做法?

EN

回答 5

Software Engineering用户

回答已采纳

发布于 2017-07-12 07:00:09

这是关于如何管理您的测试并将它们集成到您的整个环境中。我想你有条件

  • 很容易添加新的测试
  • 一次运行所有测试,也许作为测试套件的一部分。
  • 确保一个失败的测试不会阻止其他独立测试的执行。
  • 事后获取日志,其中哪些测试失败,哪些没有。
  • 在应用错误修复之后,运行测试的子集或单个测试,以验证它不会再失败。
  • 让其他人在没有特殊知识的情况下轻松地运行您的测试。

考虑到这两种解决方案,我认为通过命令行将它们参数化将使您能够更灵活地在单独运行它们与“一次性”运行它们之间进行切换,并且可以更容易地确保失败的测试不会影响其他测试。如果您有这样的需求,也许将它们集成到一个更大的测试套件中也会更容易。然而,这种灵活性并不是免费的。由于需要知道参数,所以当以错误的方式调用命令行程序时,应该会给出一个描述性消息,说明它所期望的参数类型,并且测试执行脚本应该是测试的组成部分。

因此,只要您将命令行程序与脚本一起视为一个独立的组件,只要您提供一些完整的文档,参数化方法就没有什么问题。如果这对你来说不够“自成体系”,那就把事情集成到一个程序中去,但是要接受我提到的其他需求可能需要更多的努力来解决的事实。

票数 3
EN

Software Engineering用户

发布于 2017-07-12 01:08:19

自动化测试可以参数化,而不依赖于传递的参数。通常,混合方法是最有用的。

例如,如果在没有任何命令行args的情况下运行,您的测试可能会扫描一个已配置的目录,迭代该目录中的所有映像。

在这种情况下,能够覆盖目录可能是有用的,提供命令行参数或指定环境变量是常见的方法。或者,用户可以简单地在默认目录中放置其他图像来扩展测试。

编写良好的单元测试是独立的,参数化测试意味着测试不再仅仅是一个测试。它现在是一个函数,而不是一个单元测试

@Dymeng是正确的,您的测试可能实际上是一个集成测试,而不是一个单元测试,但这并不是重点。单元测试可以参数化,集成测试也可以。

自我控制的关键是很重要的。您应该能够在您的项目上运行测试,而无需指定命令行args,因为如果其他人想要运行您的测试,则需要特殊的知识才能知道要使用哪些正确的参数来运行测试。但是,这个事实不应该阻止您公开在其他数据集上运行测试的方法。

票数 1
EN

Software Engineering用户

发布于 2017-07-12 07:15:07

很抱歉,但这是我今天听到的最糟糕的主意,原因有几点:

  • 任何执行单元测试的人都必须在正确的位置传递正确的参数,否则单元测试将失败。
  • 测试使用自己的可选参数,因此不能确定测试参数在哪里(argv、1或其他索引)。

如果实际将数据放入测试中(在变量中),并且(如果可能的话)不从文件加载数据,则是单元测试的最佳选择。

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/352579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档