如何最好地测试 Java 代码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1139136/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:11:08  来源:igfitidea点击:

How to best test Java code?

javatestinginterfacejunit

提问by Lily

I have been working on a comparatively large system on my own, and it's my first time working on a large system(dealing with 200+ channels of information simultaneously). I know how to use Junit to test every method, and how to test boundary conditions. But still, for system test, I need to test all the interfacing and probably so some stress test as well (maybe there are other things to do, but I don't know what they are). I am totally new to the world of testing, and please give me some suggestions or point me to some info on how a good code tester would do system testing.

我自己一直在做一个比较大的系统,这是我第一次在一个大系统上工作(同时处理 200 多个通道的信息)。我知道如何使用 Junit 来测试每种方法,以及如何测试边界条件。但是,对于系统测试,我需要测试所有接口,可能还需要进行一些压力测试(也许还有其他事情要做,但我不知道它们是什么)。我对测试世界完全陌生,请给我一些建议或指出一些关于优秀代码测试人员如何进行系统测试的信息。

PS: 2 specific questions I have are: how to test private functions? how to testing interfaces and avoid side effects?

PS:我有两个具体问题:如何测试私有函数?如何测试接口并避免副作用?

采纳答案by Kathy Van Stone

Here are two web sites that might help:

这里有两个网站可能会有所帮助:

The first is a list of open source Java tools. Many of the tools are addons to JUnit that allow either easier testing or testing at a higher integration level.

第一个是开源 Java 工具列表。许多工具都是 JUnit 的插件,它们允许更轻松地进行测试或在更高的集成级别进行测试。

Depending on your system, sometimes JUnit will work for system tests, but the structure of the test can be different.

根据您的系统,有时 JUnit 可用于系统测试,但测试的结构可能不同。

As for private methods, check this question(and the question it references).

至于私有方法,请检查此问题(及其引用的问题)。

You cannot test interfaces (as there is no behavior), but you can create an abstract base test classes for testing that implementations of an interface follow its contract.

您不能测试接口(因为没有行为),但是您可以创建一个抽象的基本测试类来测试接口的实现是否遵循其约定。

EDIT: Also, if you don't already have unit tests, check out Working Effectivly with Legacy Code; it is a must for testing code that is not set up well for testing.

编辑:另外,如果您还没有单元测试,请查看使用旧代码有效工作;对于没有很好地进行测试的代码,它是必须的。

回答by Paul Sonier

Mockingis a good way to be able to simulate system tests in unit testing; by replacing (mocking) the resources upon which the other component depends, you can perform unit testing in a "system-like" environment without needing to have the entire system constructed to do it.

Mocking是一种能够在单元测试中模拟系统测试的好方法;通过替换(模拟)其他组件所依赖的资源,您可以在“类系统”环境中执行单元测试,而无需构建整个系统来执行此操作。

As to your specific questions: generally, you shouldn't be using unit testing to test private functions; if they're private, they're privateto the class. If you need to test something, test a public method which uses that private method to do something. Avoiding side effects that can be potentially problematic is best done using either a complete test environment (which can easily be wiped back to a "virgin" state) or using mocking, as described above. And testing interfaces is done by, well, testing the interface methods.

至于你的具体问题:一般来说,你不应该使用单元测试来测试私有函数;如果它们是私有的,则它们是全班私有的。如果您需要测试某些内容,请测试使用该私有方法执行某些操作的公共方法。避免可能有潜在问题的副作用最好使用完整的测试环境(可以很容易地恢复到“原始”状态)或使用模拟,如上所述。测试接口是通过测试接口方法来完成的。

回答by AutomatedTester

Private functions will be tested when the public functions that call them. Your testing of the public function only cares that the result returned is correct.

当调用它们的公共函数时,将测试私有函数。您对公共函数的测试只关心返回的结果是否正确。

When dealing with API (to other packages or URLS or even to file/network/database) you should mock them. A good unit test should run in a few milliseconds not in seconds. Mocking is the only way to do that. It means that bugs between packages can be dealt with a lot easier than logical bugs at the functional level. For Java easymockis a very good mocking framework.

在处理 API(到其他包或 URL,甚至到文件/网络/数据库)时,您应该模拟它们。一个好的单元测试应该在几毫秒内运行,而不是几秒钟。模拟是唯一的方法。这意味着包之间的错误可以比功能级别的逻辑错误更容易处理。对于 Java,easymock是一个非常好的模拟框架。

回答by IRBMe

Firstly, if you already have a large system that doesn't have any unit tests, and you're planning on adding some, then allow me to offer some general advice.

首先,如果您已经有一个没有任何单元测试的大型系统,并且您打算添加一些测试,那么请允许我提供一些一般性建议。

From maintaining the system and working with it, you'll probably already know the areas of the system which tend to be buggiest, which tend to change often and which tend not to change very much. If you don't, you can always look through the source control logs (you are using source control, right?) to find out where most of the bug fixes and changes are concentrated. Focus your testing efforts on these classes and methods. There's a general rule called the 80/20 rulewhich is applicable to a whole range of things, this being one of them.

通过维护系统和使用它,您可能已经知道系统中最容易出错、经常变化和变化不大的区域。如果不这样做,您可以随时查看源代码控制日志(您正在使用源代码控制,对吗?)以找出大多数错误修复和更改的集中位置。将您的测试工作集中在这些类和方法上。有一个通用规则称为80/20 规则,它适用于所有事物,这就是其中之一。

It says that, roughly on average, you should be able to cover 80 percent of the offending cases by doing just 20% of the work. That is, by writing tests for just 20% of the code, you can probably catch 80% of the bugs and regressions. That's because most of the fragile code, commonly changed code and worst offending code makes up just 20% of the codebase. In fact, it may be even less.

它说,大致平均而言,您只需完成 20% 的工作就应该能够涵盖 80% 的违规案例。也就是说,只需为 20% 的代码编写测试,您就可以捕获 80% 的错误和回归。这是因为大多数脆弱的代码、经常更改的代码和最严重的违规代码仅占代码库的 20%。事实上,它可能更少。

You should use junit to do this and you should use something like JMockor some other mocking library to ensure you're testing in isolation. For system testing/integration testing, that is, testing things while they're working together, I can recommend FitNesse. I've had good experience with it in the past. It allows you to write your test in a web browser using simple table-like layouts, where you can easily define your inputs and expected outputs. All you have to do is write a small backing class called a Fixture, which handles the creation of the components.

您应该使用 junit 来执行此操作,并且应该使用诸如JMock或其他一些模拟库之类的东西来确保您进行隔离测试。对于系统测试/集成测试,即在它们一起工作时进行测试,我可以推荐FitNesse。我过去在这方面有很好的经验。它允许您使用简单的类似表格的布局在 Web 浏览器中编写测试,您可以在其中轻松定义输入和预期输出。您所要做的就是编写一个名为 Fixture 的小型支持类,它处理组件的创建。

回答by Michael Zilbermann

You may have a look on this list : Tools for regression testing / test automation of database centric java application?for a list of interesting tools.

您可能会查看此列表:用于以数据库为中心的 Java 应用程序的回归测试/测试自动化的工具?获取有趣的工具列表。

As you seem to already use Junit extensively it means that you're already "test infected", that is a good point...

由于您似乎已经广泛使用 Junit,这意味着您已经“测试感染了”,这是一个好点......

In my personal experience, the most difficult thing to manage is data. I mean, controlling very acutely the data agaisnt which the tests are runned.

以我个人的经验,最难管理的是数据。我的意思是,非常敏锐地控制运行测试的数据。

回答by Pablojim

The lists of tools given before are useful. From personal experience these are the tools I find useful:

之前给出的工具列表很有用。根据个人经验,这些是我觉得有用的工具:

Mocking - Mockitois an excellent implementation and has clever techniques to ensure you only have to mock the methods you really care about.

Mocking - Mockito是一个出色的实现,并具有巧妙的技术来确保您只需要模拟您真正关心的方法。

Database testing - DBunitis indespensible for setting up test data and verifying database interactions.

数据库测试 - DBunit对于设置测试数据和验证数据库交互是必不可少的

Stress testing - Jmeter- once you see passed the slightly clunky gui this is a very robust tool for setting up scenarios and running stress tests.

压力测试 - Jmeter- 一旦你看到通过了稍微笨重的 gui,这是一个非常强大的工具,用于设置场景和运行压力测试。

As for general approach start by trying to get tests running for the usual "happy paths" through your application these can form a basis for regression testing and performance testing. Once this is complete you can start looking at edge cases and error scenarios.

至于一般方法,首先尝试通过您的应用程序为通常的“快乐路径”运行测试,这些可以形成回归测试和性能测试的基础。一旦完成,您就可以开始查看边缘情况和错误场景。

Although this level of testing should be secondary to good unit testing.

尽管这种级别的测试应该次于良好的单元测试。

Good luck!

祝你好运!