标签: automated-tests

应该测试内部实现,还是仅测试公共行为?

给定软件......

  • 该系统由几个子系统组成
  • 每个子系统由几个组件组成
  • 每个组件都使用许多类实现

...我喜欢编写每个子系统或组件的自动化测试.

我没有为组件的每个内部类编写测试(因为每个类都有助于组件的公共功能,因此可以通过组件的公共API从外部测试/测试).

当我重构组件的实现时(我经常这样做,作为添加新功能的一部分),因此我不需要改变任何现有的自动化测试:因为测试仅依赖于组件的公共API和公共API通常是扩大而不是改变.

我认为这个政策与重构测试代码这样的文件形成了鲜明的对比,后者说...

  • "......单元测试..."
  • "......系统中每个班级的测试班......"
  • "......测试代码/生产代码比率...理想地被认为接近1:1的比例......"

...所有这些我认为我不同意(或至少不练习).

我的问题是,如果你不同意我的政策,你会解释原因吗?在什么情况下这种测试程度不足?

综上所述:

  • 公共接口经过测试(并经过重新测试),很少改变(它们被添加到但很少被改变)
  • 内部API隐藏在公共API之后,可以在不重写测试公共API的测试用例的情况下进行更改

脚注:我的一些"测试用例"实际上是作为数据实现的.例如,UI的测试用例包含数据文件,其中包含各种用户输入和相应的预期系统输出.测试系统意味着拥有测试代码,该代码读取每个数据文件,将输入重放到系统中,并断言它获得相应的预期输出.

虽然我很少需要更改测试代码(因为公共API通常是添加而不是更改),但我发现有时候(例如每周两次)需要更改一些现有的数据文件.当我更好地更改系统输出(即新功能改进现有输出)时可能会发生这种情况,这可能导致现有测试"失败"(因为测试代码只会尝试断言输出没有改变).要处理这些情况,我会执行以下操作:

  • 重新运行自动化测试套件,该套件有一个特殊的运行时标志,告诉它不要断言输出,而是将新输出捕获到新目录中
  • 使用可视化差异工具查看哪些输出数据文件(即哪些测试用例)已更改,并验证这些更改是否正常并且符合新功能的预期
  • 通过将新目录中的新输出文件复制到运行测试用例的目录(覆盖旧测试)来更新现有测试

脚注:通过"组件",我的意思是"一个DLL"或"一个组件"...这个大到足以在系统的体系结构或部署图上可见,通常使用数十个或100个类实现,以及因此与公共API只包含约1或接口少数......一些可能被分配到的开发商之一的团队(其中不同的组件被分配到不同的团队),并且将根据康威定律有一个相对稳定的公共API.


脚注:文章面向对象测试:神话与现实说,

神话:黑盒测试就足够了. 如果您使用类接口或规范仔细测试测试用例设计,则可以确保该类已经完全运用.白盒测试(查看方法的实现来设计测试)违反了封装的概念.

现实:OO结构很重要,第二部分.许多研究表明,开发人员认为黑盒测试套件非常彻底,只能在测试实施中使用三分之一到一半的语句(更不用说路径或状态)了.这有三个原因.首先,选择的输入或状态通常执行正常路径,但不强制所有可能的路径/状态.其次,单独的黑盒测试无法揭示惊喜.假设我们已经测试了被测系统的所有指定行为.为了确信没有未指明的行为,我们需要知道系统的任何部分是否未被黑盒测试套件执行.获取此信息的唯一方法是通过代码检测.第三,通常很难在不检查源代码的情况下执行异常和错误处理.

我应该补充一点,我正在进行白盒功能测试:我看到了代码(在实现中),我编写了功能测试(驱动公共API)来练习各种代码分支(功能实现的细节).

refactoring integration-testing automated-tests unit-testing code-coverage

44
推荐指数
4
解决办法
1万
查看次数

为iphone应用程序设置自动构建服务器的最佳实践?

我正在寻找为我们的iPhone应用程序设置自动夜间构建服务器,并寻找有效和无效的建议.

基本上,至少每晚运行所有单元测试并向我们的内部网站发布新的特殊构建.

所有开发人员都使用笔记本电脑(将在一夜之间关闭),因此我正在考虑购买专用的Mac Mini来实现这一目标.

我不确定我是否应该购买标准的Mac OS X或服务器版本.

至少对于第一次尝试,我正在考虑使用从crontab运行的简单shell脚本来完成实际工作.将来,一个完整的持续集成服务器(哈德森等)会很好.

我已经通过搜索找到了一些文章,尽管它们非常简短:

http://nachbaur.com/blog/how-to-automate-your-iphone-app-builds-with-hudson

http://blog.jeffreyfredrick.com/2008/11/27/continuous-integration-for-iphonexcode-projects/

而且这个stackoverflow问题有一些有用的软件信息(虽然现在已经两年了):

Xcode项目的持续集成?

人们可以提供有关他们如何设置构建服务器以及任何潜在问题的任何指导,我们将不胜感激.

谢谢!

约瑟夫

iphone build-automation automated-tests objective-c ipad

43
推荐指数
2
解决办法
1万
查看次数

Selenium waitForElement

如何为Selenium编写函数以等待Python中只有类标识符的表?我有一个学习使用Selenium的Python webdriver功能的魔鬼.

python automation automated-tests selenium-webdriver

42
推荐指数
3
解决办法
9万
查看次数

测试d3(和其他基于SVG的)Web应用程序

我有一个Web应用程序,它使用d3库进行一些基于SVG的复杂可视化.

我对我的服务器端代码和JavaScript模型进行了自动化测试(我在JavaScript中使用了类似MVC的体系结构).这些都在每次提交时在Jenkins CI服务器上运行.现在我需要弄清楚如何测试我的观点.

别人如何解决这个问题以及你使用什么工具?

我有过一些想法......

  • 将生成的SVG序列化为文件并与基线进行比较
  • 自动捕获浏览器图像并执行图像差异
  • 别的什么?

谢谢!

javascript browser svg automated-tests d3.js

39
推荐指数
2
解决办法
6373
查看次数

自动生成.NET单元测试

有单元测试生成这样的东西吗?如果是这样...

......它运作良好吗?

... .NET可用的自动生成解决方案是什么?

......有使用这种技术的例子吗?

...这仅适用于某些类型的应用程序,还是可以用来替换所有手动编写的单元测试?

.net c# automation automated-tests unit-testing

38
推荐指数
3
解决办法
3万
查看次数

提升测试与Google测试框架

我是单元测试世界的新手,基本上我是c ++开发人员,在大型产品上工作了近3年,现在我决定对我的代码进行自动单元测试.为此,我在互联网上做了很多研究并遇到了许多工具和框架,最后选择了以下两个:1)Boost测试库2)c ++的Google测试框架

现在我很困惑哪些可供选择.如果有人使用上述任何一项,请分享您的经验.

boost automated-tests unit-testing googletest

38
推荐指数
3
解决办法
3万
查看次数

测试webforms应用程序的最佳方法是什么(ASP.NET)

测试我的webforms应用程序的最佳方法是什么?

看起来人们喜欢Watin和硒.

asp.net automated-tests webforms

37
推荐指数
3
解决办法
2万
查看次数

编写"单元可测试"代码?

您使用什么样的实践来使您的代码更适合单元测试?

language-agnostic automated-tests unit-testing

37
推荐指数
7
解决办法
5784
查看次数

在Django中测试"不同层"的最佳实践是什么?

不是新手测试,但是对于在Django中测试不同层的一堆建议感到非常困惑.

一些人建议(并且他们是对的)避免模型中的Doctests因为它们不可维护...

其他人说不使用灯具,因为它们比辅助功能灵活性差,例如..

还有两组人在争取使用Mock对象.第一组相信使用Mock并隔离系统的其余部分,而另一组则更喜欢停止模拟 并开始测试 ..

我上面提到的,主要是关于测试模型.功能测试是另一个故事(使用test.Client()VS webTest VS等)

是否有任何可维护,可行且适当的方法来测试不同的层?

UPDATE

我知道Carl Meyer在PyCon 2012上的演讲.

testing django tdd automated-tests django-testing

37
推荐指数
2
解决办法
3388
查看次数

如果指定了"-DskipTests"或"-Dmaven.test.skip = true",如何跳过Maven插件执行?

我正在使用Maven 3.0.3.我有这个插件,通常我想在执行JUnit测试之前运行它:

    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <test.mysql.db.user>sbjunituser</test.mysql.db.user>
            <test.mysql.db.password></test.mysql.db.password>
            <test.mysql.db.prefix>sbjunit</test.mysql.db.prefix>
            <test.mysql.db.sid>${test.mysql.db.prefix}_${project.artifactId}</test.mysql.db.sid>
            <test.mysql.db.host>localhost</test.mysql.db.host>
            <test.mysql.db.port>3306</test.mysql.db.port>
            <test.mysql.dataSource.url>jdbc:mysql://${test.mysql.db.host}:${test.mysql.db.port}/${test.mysql.db.sid}</test.mysql.dataSource.url>
            <test.mysql.dataSource.driverClassName>com.mysql.jdbc.Driver</test.mysql.dataSource.driverClassName>
        </properties>
        <build>
            <plugins>
        <!--  Run the liquibase scripts -->
        <plugin>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-maven-plugin</artifactId>
            <version>2.0.1</version>
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>5.1.18</version>
                </dependency>
            </dependencies>
            <executions>
                <execution>
                    <id>build-database</id>
                    <phase>process-test-classes</phase>
                    <configuration>
                        <driver>com.mysql.jdbc.Driver</driver>
                        <url>jdbc:mysql://${test.mysql.db.host}:${test.mysql.db.port}/${test.mysql.db.sid}</url>
                        <username>${test.mysql.db.user}</username>
                        <password>${test.mysql.db.password}</password>
                        <changeLogFile>${project.build.directory}/db.changelog-master.xml</changeLogFile>
                        <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
                    </configuration>
                    <goals>
                        <goal>update</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
Run Code Online (Sandbox Code Playgroud)

但是,如果有人指定-Dmaven.test.skip=true或者-DskipTests,我想跳过这个插件来运行.我怎么做?我尝试将执行阶段更改为"test",但之后我的单元测试在此插件之前运行,这不是我想要的.

testing plugins automated-tests maven

37
推荐指数
4
解决办法
4万
查看次数