您的位置:首页 > 编程语言 > Java开发

[转载]在Eclipse中使用 JUnit(Using JUnit With Eclipse IDE)

2015-05-13 21:02 423 查看
This article is going to introduce you to JUnit, a tool for project testing and debugging. After introducing the theory of test-driven development, we'll move on to a step-by-step explanation of how you can create your JUnit tests with the help of the popular Eclipse IDE. 这篇文章将向你介绍Junit,一个用来在项目中进行测试和调试的工具。在介绍完TDD(以测试驱动开发)理论后,将进一步讲解怎样在流行的Eclipse中建立你自己的JUnit测试。向你展示如何测试Hello World这样简单的程序...... 在 Eclipse 中使用 JUnit(翻译)
这篇文章将向你介绍Junit,一个用来在项目中进行测试和调试的工具。在介绍完TDD(以测试驱动开发)理论后,将进一步讲解怎样在流行的Eclipse中建立你自己的JUnit测试。向你展示如何测试Hello World这样简单的程序。

许多书上都讨论了自动测试,但是只有很少的著作注意到这么一个问题,那就是怎样把这些测试组织起来。随着测试的增加,放置和调用这些测试却变得更加麻烦。这将成为一个重要问题,以至于出现了TDD,极限编程(XP)使TDD得以普及。另外,你可以这样理解TDD:通过测试来开发。

TDD的主要规范:

在编写程序代码之前,与之对应的自动测试必须被写好。甚至程序代码并不存在,那也要看见一个失败的测试结果。
在测试通过后,副本代码必须被丢弃。

有一个具体步骤(可能指的是《Extreme Programming》)可以被任何一个程序员来参考,而不需要特殊的其他方法。在我们开始写测试之前,这些步骤(章节)应该被首先阅读——怎样组织自动测试。

讲解一下不同种类的测试:

单元测试:检测模块(也就是类)的正确性。如果对象需要访问外部的数据资源,例如数据库,就需要模拟一个mock objects,但在实际中真实数据与测试环境是不同的。
客户测试:这是功能性、系统、和验收测试。用来测试整体的系统特性。在XP中,这些测试由用户编写。
综合测试:介于用户测试和单元测试之间的桥梁。综合测试帮助测试应用程序的交互性。一般情况下,mock objects不被用于综合测试,它会增加测试时间。同样,综合测试经常依赖特殊的测试环境,例如数据库送来的测试数据。综合测试也需要用到外部类库。例如为J2EE应用程序进行综合测试的类库Cactus。解释这些测试超出了本文的范围,需要更加详细的信息请参考http://jakarta.apache.org/cactus/
开发人员测试:这是用来让开发人员检验自己代码或新函数的。对于每一个开发人员,只要有可能,就需要有更多的测试来检验代码。组织这些测试和组织程序代码一样重要。

在以下章节,只要提到“测试”,那就指的是开发人员测试。

我们几乎准备好开始建立测试了,先应该为我们的测试选择名字。你也许会说,“这不是问题:把‘Test’这个字放在类名前面,就好了!”不会这么快!让我来说一下这个步骤存在的问题:

在TDD中,被测试的类或者方法还不存在。
一个测试能够覆盖多个方法,甚至多个类,这是可能的。

以上只是一些普遍问题;还存在更多的问题。

让我来提一个建议,在测试命名时:测试类的名字应该让人一眼就知道这是一个测试类,且能说明它要测试什么,注意是否和其他类重名。按照以上建议做,就很简单了,也不用担心名字太长或难听。

即将在Eclipse中用JUnit工具创建我们第一个测试了。假设你已经下载了一个最新的Eclipse版本。如果还没有,你应该去官方站点http://www.eclipse.org下载。还需要JUnit,也可以从http://www.junit.org/下载。

运行Eclipse。新建一个workplace项目,点击文件->新建->项目,选择Java项目,点击下一步。起一个项目名称,例如ProjectWithJUnit。点击完成。这样就完成新项目的建立了。再来配置一下Eclipse,在构建路径中添加JUnit类库。在工具条上点击项目->属性,选择Java构建路径,选择添加外部JAR,浏览Junit被存储的目录,选择junit.jar,点击打开。你将会看见JUnit出现在库的列表中。点击确定,让Eclipse重建路径。

现在开发我们的“Hello World”例子。按照TDD的规则,应该在代码建立以前先把测试写好。为了能够在某出开始,我们假设未来的类名是HelloWorld,并且有一个方法Say(),这个方法返回String的值(例如“Hello World!”)。

建立测试,在ProjectWithJUnit的标题上面点击右键,选择新建->其他,展开“Java”选项,选择JUnit。在右边的栏目对话框中选择测试案例,然后下一步。参考图1。



图1. 在Eclipse中建立JUnit测试

在测试类这一栏中,写上将要被测试的类名HelloWorld。选择一个测试案例的名字,例如TestThatWeGetHelloWorldPrompt(是的,看上去很长,但是很清楚它的行为。)点击完成

TestThatWeGetHelloWorldPrompt的代码如下:
import junit.framework.TestCase;
public class TestThatWeGetHelloWorldPrompt
extends TestCase {
public TestThatWeGetHelloWorldPrompt(
String name) {
super(name);
}
public void testSay() {
HelloWorld hi = new HelloWorld();
assertEquals("Hello World!", hi.say());
}
public static void main(String[] args) {
junit.textui.TestRunner.run(
TestThatWeGetHelloWorldPrompt.class);
}
}
代码并不复杂;只是有点与众不同。然而,让我们考察一下细节。我们继承了JUnit的TestCase类,它在JUnit的javadocs定义为“运行众多测试的夹具。”JUnit也有TestSuite类,它是一组测试案例的集合,但在本文中不做讨论。
建立测试案例的步骤如下:
1、建立一个junit.framework.TestCase的实例。
2、定义一些以“test”开头的无返回方法(例如testWasTransactionSuccessful(),testShow(),等等)。
TestThatWeGetHelloWorldPrompt.java包含这些:TestCase的子类和一个叫做testSay()的方法。这个方法调用了assertEquals()函数,它用来比较我们预期的值和由say()返回的值。

main()方法用来运行测试和显示输出的。JUnit的TestRunner处理测试,提供基于图像和文本的输出表现形式。我们使用基于文本的版本,因为Eclipse支持它,且也适合我们。当开始运行后,基于文本的版本测试会以文本形式输出,Eclipse会把这些输出自动变成图像界面的输出。

按照TDD规范,首次运行测试,应该故意让它失败。点击运行->运行为->Junit测试(记住TestThatWeGetHelloWorldPrompt.java应该被突出的显示在包资源管理器中)。在左边窗口,应该看见JUnit窗口而不是包资源管理器,它显示一个红条,一次失败的测试,具体的失败原因参看图2。如果没有自动显示这些内容,点击JUnit标签(在底部的左边)。



图2. JUnit中失败的测试

很好!的却失败了。现在我们来建立被测试代码:在包资源管理器窗口的ProjectWithJUnit标题上右击,选择新建->。选择类名,我们已经假设了它叫HelloWorld,然后直接点击完成。为HelloWorld.java填入下列代码:
public class HelloWorld {
public String say() {
return("Hello World!");
}
}

这段代码很简单,甚至不需要注解,我们再来看看结果。按照上面描述过的方式,在JUnit的窗口中显示了一个绿条,参看图3。绿条证明测试成功。



图3. JUnit中成功的测试

现在,我们想再让测试失败一次,但原因不同。这有助于展示JUnit测试中不同的报错信息。修改assertEquals()代码,把“Hello World!”变成“Hello Me!”。当再次运行JUnit时,结果变成了红条,在JUnit窗口的底部输出了失败原因,参看图4。



图4. JUnit中的ComparisonError

最后,我想说一下关于测试是开发过程中的必要部分的话题。测试代码一直是开发中的重要部分。经过近几年的发展,已得到了很大的提高,这要归功于强大的理论研究(比如“expectations-based development”等等),和快速发展的测试工具包,还有测试过程的改进。如果你对这篇文章感兴趣,那请你花一些时间来正式的学习一下测试理论吧,这对你的工作很有用。
关于作者:
Alexander Prohorenko 一名UNIX系统管理员、网络安全管理员。
[align=left] Olexiy Prohorenko 一名Java开发者居住在乌克兰的Dniepropetrovsk。
译者:Rosen Jiang
译文原址:http://blog.csdn.net/rosen[/align]
[align=left][/align]
[align=left][/align]

Using JUnit With Eclipse IDE

[align=left]by Alexander Prohorenko and Olexiy Prohorenko
02/04/2004 [/align]
[align=left][/align]
This article is going to introduce you to JUnit, a tool for project testing and debugging. After introducing the theory of test-driven development, we'll move on to a step-by-step explanation of how you can create your JUnit tests with the help of the popular Eclipse IDE. We'll show how something as simple as a Hello World program can be exposed to a JUnit test.
Many books have already been written about automated testing, but very few of them pay attention to the question of how to organize such tests. As more tests are written, it becomes harder to know where to put a test or even what to call it. This has become a significant issue with the rise of test-driven development (TDD), which has been popularized by Extreme Programming (XP). You can think of TDD as "development through testing."
The major provisions of TDD are:
Before writing any code fragment, an automated test must be written to check the functioning of this code. Since the code does not exist yet, it initially fails the test.
After the test begins to pass, duplicate code must be removed.
Such an approach can be used by any programmer and does not require the use of a specific methodology. But before we get into writing tests, it would be desirable to first look at how to organize the automated tests.
There several different kinds of tests we should consider:
Related Reading
Extreme Programming Pocket Guide
By chromatic

Table of Contents
Index
Unit tests: These serve to check the correctness of several modules (i.e., classes). If the object needs access to some external data source, like a database, these are simulated with mock objects, but only in cases in which re-creating the actual data source would be difficult in a test environment.

Customer's tests: These are functional, system, and acceptance tests. All of them check the behavior of the system as a whole. In the XP methodology, these tests are written by the customer, given the program skeleton.

Integration tests: These are like a cross between the customer tests and unit tests. Integration tests help test the interaction of several levels of the application. Typically, mock objects are not used in integration testing, which may increase testing time. Also, integration tests often demand the presence of a special test environment, such as a database seeded with test data. Integration tests may also use special external libraries. An example of such a library for the integration of J2EE applications is Cactus. Explanation of these tests is going beyond of this article, and requires much detailed theory information, so you just take it as information that such kind of tests exists.

Developer's tests: These are just tests that developers use to verify whole code, new pieces of code, and/or new functions. For each developer, it is important to generate new tests to check code whenever possible. Organizing these tests can be as important as organizing the code base itself.

For the rest of this article, when I say "test," I will mean developer's test.
During development, a programmer sometimes asks himself or herself: is there a test for the given behavior of the system and if it exists, where it can be found? A classic example is basic bug fixing, in which the mistake is found, but not by automated tests. The sequence of events that results from this situation might be:
Look for a test for the given functionality (it's probable that the test is already written, but contains a mistake).
If such test is not present, or it does not cover a situation in which there is a mistake, we will need to write a new test that reveals it.
Now we need to be convinced that the new test does not pass.
Fix the bug.
Run the test.
Confirm that it passes.
Certainly, variations of this process are possible, but the idea should be clear: you only correct a mistake when you have a test that reveals the mistake.
Now, let's consider how a developer would solve this situation. To search through existing functionality tests:
We can take advantage of certain integrated development environments (IDEs) that allow us to search for places in which corrected classes and methods are used.
Create a known error situation and inspect what fragment of code is in error.
Last but not least, write the test and place it in one of the existing test classes. If you make a mistake arranging your test and duplicate test code, hopefully you or one of your colleagues will eventually notice the duplication and correct it.
We are almost ready to create our test, so now we have to choose a name for our test. You could say, "It's not even a problem: just put the word "Test" before your class name, and that's it!" But not so fast! Let me just show how this approach can run into trouble:
When using TDD, the class or method to be tested may not exist yet.
It's also possible that one test can cover several methods, or even several classes.
These are just the most common problems; there are many more.
Let me offer one recommendation on naming your tests: the name of a test class should convey that this class is a test class, and indicate what exactly it checks, whether or not it repeats the name of a tested class. That's easy. Don't worry if such a name turns out too long or ugly. It describes itself, and that is the idea.
We will create our first test with the help of the JUnit tool in the Eclipse IDE. I assume that you have already downloaded a recent version of this product, but if not, you can always get it from the official site. We need JUnit, which you can download from its official site, too. Download it and unzip somewhere on your disk, where you are keeping your Java libraries.
Run Eclipse IDE. We will create a new workplace project, so click File -> New -> Project, then choose Java and click Next. Type in a project name -- for example, ProjectWithJUnit. Click Finish. The new project will be generated in your IDE. Let's configure our Eclipse IDE, so it will add the JUnit library to the build path. Click on Project -> Properties, select Java Build Path, Libraries, click Add External JARs and browse to directory where your JUnit is stored. Pick junit.jar and click Open. You will see that JUnit will appear on your screen in the list of libraries. By clicking Okay you will force Eclipse to rebuild all build paths.
We are ready to start developing our "Hello World" example. Let's follow TDD rules and create the test even before we have any kind of code. For the sake of having somewhere to start, we will assume that our future code class will be named HelloWorld and that it will have the method say(), which will return some String value ("Hello World," for example).
To create such a test, right-click on the ProjectWithJUnit title, select New -> Other, expand the "Java" selection, and choose JUnit. On the right column of the dialog, choose Test Case, then click Next. This is illustrated by Figure 1.

Figure 1. Creating a JUnit test in the Eclipse IDE
Type in the name of our yet-to-be written class HelloWorld into the Test class field, and choose a name for our Test case -- for example, TestThatWeGetHelloWorldPrompt (yes, it looks too long, but it clearly indicates what it does.) Click on Finish.
The code for TestThatWeGetHelloWorldPrompt.java is as follows:
import junit.framework.TestCase;  public class TestThatWeGetHelloWorldPrompt     extends TestCase {     public TestThatWeGetHelloWorldPrompt(         String name) {         super(name);     }     public void testSay() {         HelloWorld hi = new HelloWorld();         assertEquals("Hello World!", hi.say());     }     public static void main(String[] args) {         junit.textui.TestRunner.run(             TestThatWeGetHelloWorldPrompt.class);     } }
This code is not complex; it's just a bit unusual. However, let's examine it in detail. We extend JUnit's TestCase class, which is defined in JUnit's javadocs as "a fixture to run multiple tests." JUnit also has TestSuite, which is a set of related test cases, but we will not work with in this article.
[align=right][/align]
[align=left]To create our own simple test case, we need to follow these steps: [/align]
Create an instance of junit.framework.TestCase.
Define tests that return void and whose name begins with the string "test" (such as testWasTransactionSuccessful(), testShow(), etc.).

TestThatWeGetHelloWorldPrompt.java meets both of these criteria: it subclasses TestCase and has a method called testSay(). This method uses an assertEquals() call, which compares the value which we expect to receive against the value returned by say().
The main() method is used to run the tests and present their output. JUnit's TestRunner executes our tests, and provides both graphical and textual output. We use the textual version because that's what Eclipse IDE supports and it's absolutely suitable for us. Once executed, the textual version of the test shows the result as text output and Eclipse IDE uses that to create its own graphic presentation.
So, according TDD provisions, once we run our test we should see that it failed. Let's try. Click Run -> Run as -> JUnit Test (remember that TestThatWeGetHelloWorldPrompt.java should be highlighted in Package Explorer). In the left window, instead of Package Explorer, you will see the JUnit window, which shows a red bar, the failed tests, and details of those failures, as seen in Figure 2. If you do not automatically see it, just click on JUnit label (on the bottom left), which is one of the layers of this screen.

Figure 2. Failed test in JUnit
Perfect! It really fails. Now we can create working code in our project: right-click the ProjectWithJUnit title in the left Package Explorer window, then choose New -> Class. Choose a name for the class — we've assumed it to be HelloWorld. Do not check off any of checkboxes on the bottom of the dialog window, just click Finish. Below is the code for HelloWorld.java:
public class HelloWorld {     public String say() {         return("Hello World!");     } }
It's very simple and merits no commentary. So let's test it and see the results. Run our test the same way as described above, and in the left JUnit window you will see a green bar, as seen in Figure 3. The green bar means that our test was successful.

Figure 3. Successful test in JUnit
Now we want to try to make it fail once again, but for a different reason. This will help show how JUnit test covers and reports different errors. Edit the assertEquals() to change the expected return value from "Hello World!" to, for example, "Hello Me!". When you run this JUnit test again, the bar will be red, and at the bottom of the left JUnit window you will see an explanation of what failed, as illustrated by Figure 4.

Figure 4. ComparisonError running JUnit
In conclusion, I would like to mention a few thoughts about testing as a necessary part of the development process. Testing code was always an integral part of any development. But it has been advanced over the last few years, thanks to powerful methodologies (such as "expectations-based development," etc.), accelerated testing toolkits, and the development of better testing processes. If you have found this article interesting, take some time to study formal testing methodology, and use it in your work.
Alexander Prohorenko is a certified professional, who holds Sun Certified System Administrator and Sun Certified Java Programmer certifications.
Olexiy Prohorenko is a燬un Certified Enterprise Architect whose areas of interests include Web software architecture and development of software爓ith frequently changing requirements.
Return to ONJava.com.
Copyright © 2006 O'Reilly Media, Inc.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: