JUnit In Action 笔记

第二章 Exploring JUnit
1.JUnit类

TestCase
TestSuite -- Designed to run one or more test cases
BaseTestRunner  -- Launches the TestSuite

2.Composite pattern 在JUnit中的应用
TestSuite and TestCase 都实现了Test接口,在TestSuite增加Test对象,意味着你可以增加TestSuite去运行一组test,或者增加TestCase去运行一个test。

public class TestAll
{
public static Test suite()
{
TestSuite suite = new TestSuite("All tests from part 1");
suite.addTestSuite(TestCalculator.class);
suite.addTestSuite(TestDefaultController.class);
// if TestDefaultController had a suite method
// (or alternate suite methods) you could also use
// suite.addTestSuite(TestDefaultController.suite());
return suite;
}
}

3.Failures and errors
JUnit 区分 failures 和 errors.
Failures是能够被预计的,比方说代码改变引起的Failure。
Error 是不能被预期的,如网络连接失败之类的错误.   

第四章 Examining Software Tests


软件测试的几种类别:
1.Unit test
2.Integration test 集成测试
3.Feature test 功能测试                use case
4.Stress/Load test 压力测试            
5.Acceptance test 验收测试

Stress/Load test 的工具
JMeter        http://jakarta.apache.org/jmeter
JUnitPerf     

代码覆盖率测试
Clover    http://www.thecortex.net/clover/        
Jester

Question:
    在没有集成测试前能做功能测试吗?公司的Software process为Component先做功能测试,再集成测试。

第五章 Automating JUnit

JUnit + Ant

已经有持续测试的框架CruiseControl
http://blog.csdn.net/chelsea/archive/2004/11/22/190545.aspx

第六章 Coarse-grained testing with stubs
Stubs Objects

1. 定义
运行时动态插入的用于替代真实环境的对象。
stub—A stub is a portion of code that is inserted at runtime in place of the real code, in order to isolate calling code from the real implementation.

2. 适用性
粗粒度

3. 缺点
编写、调试、维护过于复杂

4. 工具
Jetty (Stubbing the web server’s resources)
内嵌的服务器(embedded server),通过继承它的ResourceHandler类,可模拟web服务器响应的内容.
http://jetty.mortbay.org/jetty/index.html

启动Jetty
HttpServer server = new HttpServer();

SocketListener listener = new SocketListener();
listener.setPort(8080);//绑定listener到8080端口,接受HTTP的request
server.addListener(listener);

HttpContext context = new HttpContext();
context.setContextPath("/");
context.setResourceBase("./");
context.addHandler(new ResourceHandler());
server.addContext(context);

server.start();

5.实例
TestCase中的代码
public class TestWebClientSkeleton extends TestCase
{
protected static HttpServer server;

protected void setUp()
{
server = new HttpServer();

SocketListener listener = new SocketListener();
listener.setPort(8080);
server.addListener(listener);

HttpContext context1 = new HttpContext();
context1.setContextPath("/testGetContentOk");
context1.addHandler(new TestGetContentOkHandler());
server.addContext(context1);

server.start();
}
protected void tearDown()
{
server.stop();
}
public void testGetContentOk() throws Exception
{
WebClient client = new WebClient();
String result = client.getContent(new URL("http://localhost:8080/testGetContentOk"));
assertEquals ("It works", result);
}
}

实现Jetty的Handle类
private class TestGetContentOkHandler extends AbstractHttpHandler
{
public void handle(String pathInContext, String pathParams,HttpRequest request, HttpResponse response)throws IOException
{
OutputStream out = response.getOutputStream();
ByteArrayISO8859Writer writer =new ByteArrayISO8859Writer();
writer.write("It works");
writer.flush();
response.setIntField(HttpFields.__ContentLength,writer.size());
writer.writeTo(out);
out.flush();
request.setHandled(true);
}

6.TestSetup in TestCase
为所有的TestCase提供全局的setUp和tearDown
Extend TestSetup to provide global setUp and tearDown

比方说所有的TestCase都需要在setUp中启动Jetty Server,则不该在每个TestCase中做此事。
通过继承TestSetup,把全局的创建资源的代码放在setUp里。

import junit.extensions.TestSetup;
public class TestWebClientSetup1 extends TestSetup
{
protected static HttpServer server;
public TestWebClientSetup1(Test suite)
{
super(suite);
}
protected void setUp() throws Exception{
...//The code should be here
}
}

配置TestSetup
public class TestWebClient1 extends TestCase
{
public static Test suite()
{
TestSuite suite = new TestSuite();
suite.addTestSuite(TestWebClient1.class);
return new TestWebClientSetup1(suite);
}
...
}

第七章 Testing in isolation with mock objects
mock object

1.定义
mock object—A mock object (or mock for short) is an object created to
stand in for an object that your code will be collaborating with. Your
code can call methods on the mock object, which will deliver results
as set up by your tests.

2.最佳实践
2.1 Don't write business logic in mock objects
stub正相反,包含逻辑。

2.2 Only test what can possibly break

3.适应性
Real object has non-deterministic behavior
Real object is difficult to set up
Real object has behavior that is hard to cause (such as a network error)
Real object is slow
Real object has (or is) a UI
mock object作为重构的一种手段

4.优势
mock object 简单(因为不包括逻辑)
mock object是一个空壳(empty shell),它自身不需要测试

5.实例
5.1 需要被测试的类
public class WebClient
{
public String getContent(URL url)
{
StringBuffer content = new StringBuffer();
try
{
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
InputStream is = connection.getInputStream();
byte[] buffer = new byte[2048];
int count;
while (-1 != (count = is.read(buffer)))
{
content.append(new String(buffer, 0, count));
}
}
catch (IOException e)
{
return null;
}
return content.toString();
}
}
当你希望使用mock对象来测试,如下:
public void testGetContentOk() throws Exception
{
MockHttpURLConnection mockConnection =new MockHttpURLConnection();
mockConnection.setupGetInputStream(new ByteArrayInputStream("It works".getBytes()));
MockURL mockURL = new MockURL();
mockURL.setupOpenConnection(mockConnection);

WebClient client = new WebClient();
String result = client.getContent(mockURL);
assertEquals("It works", result);
}
这样却行不通,很难生成mock对象,因为URL是final类,不能通过继承URL实现mock对象
mock test帮助重构,产生灵活的代码
书中提供了两种重构方法
一种方法是通过增加接口,类中主要测试的是从URL中取出的Connection。增加一个setConnection和getConnection的方法,允许外部设置Connection(IOC),类里使用getConnection的方法调用Connection实例来获得Connection的mock类来对Connection测试。

另外一种方法是修改原有的接口,把getContent的参数类型由URL改成引入一个新的工厂类型,定义新的连接工厂,直接返回输入流。代码如下
public interface ConnectionFactory
{
InputStream getData() throws Exception;
}

public String getContent(ConnectionFactory connectionFactory)
{
...
InputStream is = connectionFactory.getData();
...
}

但如果要对第三方的库,不能修改,而又没有良好的设计,则mock不太合适。

第八章 In-container testing with Cactus

测试 Servlet的两种方式
Stub container:HttpUnit (http://httpunit.sourceforge.net/).

8.1 Outside-the-container testing with mock objects for Servlet
8.1.1 概述
EasyMock 用JDK的dynamic proxy实现
http://www.easymock.org/


8.1.2 实例
需要测试的Servlet代码
public class SampleServlet extends HttpServlet
{
public boolean isAuthenticated(HttpServletRequest request)
{
HttpSession session = request.getSession(false);
if (session == null)
{
return false;
}
String authenticationAttribute =(String) session.getAttribute("authenticated");
return Boolean.valueOf(authenticationAttribute).booleanValue();
}
}

EasyMock的模拟代码
import org.easymock.MockControl;

public class TestSampleServlet extends TestCase
{
private SampleServlet servlet;
private MockControl controlHttpServlet;
private HttpServletRequest mockHttpServletRequest;
private MockControl controlHttpSession;
private HttpSession mockHttpSession;

protected void setUp()
{
servlet = new SampleServlet();
controlHttpServlet = MockControl.createControl(HttpServletRequest.class);
mockHttpServletRequest =(HttpServletRequest) controlHttpServlet.getMock();

controlHttpSession = MockControl.createControl(HttpSession.class);
mockHttpSession =(HttpSession) controlHttpSession.getMock();
}

protected void tearDown()
{
controlHttpServlet.verify();
controlHttpSession.verify();
}

public void testIsAuthenticatedAuthenticated()
{
mockHttpServletRequest.getSession(false);
controlHttpServlet.setReturnValue(mockHttpSession);

mockHttpSession.getAttribute("authenticated");
controlHttpSession.setReturnValue("true");

controlHttpServlet.replay();
controlHttpSession.replay();
assertTrue(servlet.isAuthenticated(mockHttpServletRequest));
}
}

8.1.3 缺点
a. 缺乏与容器的交互测试
b. 缺乏component的部署测试
c. 需要额外的API知识(如Servlet)
d.

8.2 In-container testing using Cactus for Sevelet.
8.2.1 工具
Cactus http://jakarta.apache.org/cactus/

8.2.2 定义
A unit-testing framework specializing in integration unit-testing for server-side Java components.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JUnit学习笔记精要》是一本介绍JUnit测试框架的学习资料,可以从CSDN下载。JUnit是一个开源的Java单元测试框架,用于简化和自动化开发者编写和执行单元测试的过程。JUnit的学习对于提高代码质量、减少bug的产生以及提高开发效率具有重要意义。 这本《JUnit学习笔记精要》将帮助读者从零开始掌握JUnit的基本概念和用法。书中首先介绍了JUnit的起源和发展历程,让读者了解JUnit的背景和重要性。然后详细讲解了JUnit的安装和配置,帮助读者快速上手使用该测试框架。 接下来,书中深入介绍了JUnit的各种注解和断言方法。JUnit的注解用于标记测试方法,通过使用不同的注解,可以控制测试方法的执行顺序、重复执行次数等。而JUnit的断言方法则用于验证测试结果是否符合预期。书中通过大量的示例代码和实际案例,详细讲解了如何使用这些注解和断言方法。 此外,书中还介绍了如何构建复杂的测试套件、如何使用参数化测试和如何处理异常测试。这些高级主题能够帮助读者进一步提升自己的单元测试技能,实现更全面的测试覆盖和更准确的测试结果。 总之,《JUnit学习笔记精要》是一本系统、实用的学习资料,适合想要学习JUnit的开发者。通过下载这本书,读者可以更好地理解和掌握JUnit的各种概念和用法,提高软件开发的质量和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值