当前位置:天才代写 > tutorial > JAVA 教程 > 追求代码质量 – 用JUnitPerf举办机能测试

追求代码质量 – 用JUnitPerf举办机能测试

2017-11-10 08:00 星期五 所属: JAVA 教程 浏览:806

副标题#e#

在应用措施的开拓中,验证应用措施的机能险些总处于次要的职位。请留意 ,我强调的是验证 应用措施的机能。应用措施的机能老是 首要思量的因素,但 开拓周期中却很少包括对机能的验证。

由于各种原因,机能测试常被延迟到开拓周期的后期。以我的履历,企业之 所以在开拓进程中不包括机能测试是因为,他们不知道对付正在举办开拓的应用 措施要等候什么。提出了一些(机能)指数,但这些指数是基于预期负载提出的 。

产生下列两种环境之一时,机能测试就成为头等大事:

出产中呈现显而易见的机能问题。

在同意付费之前 ,客户或潜在客户询问有关机能指数的问题。

本月,我将先容两种简朴的机能测试技能,在上述两种环境中的任何一种发 生前举办测试。

用 JUnitPerf 举办测试

在软件开拓的早期阶段,利用 JUnit 很容易确定根基的低端机能指数。JUnitPerf 框架可以或许将测试快速地转化为简朴的负载测试,甚至压力测试。

可利用 JUnitPerf 建设两种测试范例:TimedTest 和 LoadTest。这两种类 型都基于 Decorator 设计模式并操作 JUnit 的 suite 机制。TimedTest 为测 试样例建设一个(时间)上限 —— 假如高出这个时间,那么测试失败。 LoadTest 和计时器一起运行,它通过运行所需的次数(时距离断由设置的计时 器节制),在一个特定的测试用例上建设一小我私家工负载。

得当的时限测试

JUnitPerf TimedTest 让您可以编写有相关时间限制的测试 —— 假如高出 了该限度,就认为测试是失败的(即便测试逻辑自己实际上是乐成的)。在测试 对付业务致关重要的要领时,时限测试对比其他测试来说,在确定和监控机能指 数方面很有辅佐。甚至可以测试得越发细致一些,可以测试一系列要领来确保它 们满意特定的时间限制。

譬喻,假设存在一个 Widget 应用措施,个中,特定的对付业务致关重要的 要领(如 createWidget())是严格的机能限制的测试方针。假设需要对执行该 create() 要领的成果方面举办机能测试。这凡是会由差异的团队利用差异的工 具在开拓周期的后期加以确定,这凡是不能指出准确的要领。但假设抉择选择早 期常常测试 要领取而代之。

建设 TimedTest 首先要建设一个尺度的 JUnit 测试。换言之,将对 TestCase 或其派生类举办扩展,并编写一个以 test 开头的要领,如清单 1 所 示:

清单 1. 简朴的 widget 测试

public class WidgetDAOImplTest  extends TestCase {
  private WidgetDAO dao;

  public void testCreate() throws Exception{
  IWidget wdgt = new Widget();
  wdgt.setWidgetId(1000);
  wdgt.setPartNumber("12-34-BBD");
  try{
   this.dao.createWidget(wdgt);
  }catch(CreateException e){
   TestCase.fail("CreateException thrown creating a  Widget");
  }
  }

  protected void setUp() throws Exception {
  ApplicationContext context =
   new ClassPathXmlApplicationContext("spring-config.xml");
  this.dao = (WidgetDAO) context.getBean("widgetDAO");
  }
}


#p#副标题#e#

由于 JUnitPerf 是一个基于装饰器的框架,为了真正地驾御它,必需提供一 个 suite() 要领并将现有的测试装饰以 TimedTest。TimedTest 以 Test 和执 行该测试的最大时间量作为参数。

也可以选择传入一个 boolean 符号作为第三个参数(false),这将导致测 试快速失败 —— 意味着假如高出最大时间,JUnitPerf 将当即 迫使测试失败 。不然,测试样例将完整运行,然后失败。区别很微妙:在一个失败的样例中, 不带可选符号运行测试可以帮您相识运行总时间。传入 false 值却意味着得不 到运行总时间。

譬喻,在清单 2 中,我在运行 testCreate() 时设定了一个两秒钟的上限。 假如执行总时间高出了这个时间,测试样例将失败。由于我并未传入可选的 boolean 参数,该测试将完整运行,而不管运行会一连多久。

清单 2. 为生成 TimedTest 而实现的 suite 要领

public static  Test suite() {
  long maxElapsedTime = 2000; //2 seconds
  Test timedTest = new TimedTest(
   new WidgetDAOImplTest("testCreate"), maxElapsedTime);
  return timedTest;
}

此测试凡是在 JUnit 框架中运行 —— 现有的 Ant 任务、Eclipse 运行器 等等,会像运行任何其他 JUnit 测试一样运行这个测试。惟一的差异是,该测 试将产生在计时器的上下文中。

太过的负载测试

#p#分页标题#e#

与在测试场景中验证一个要领(或系列要领)的时间限制正好相反, JUnitPerf 也利便了负载测试。正如在 TimedTest 中一样,JUnitPerf 的 LoadTest 也像装饰器一样运行,它通过将 JUnit Test 和特另外线程信息绑定 起来,从而模仿负载。

利用 LoadTest,可以指定要模仿的用户(线程)数量,甚至为这些线程的启 动提供计机缘制。JUnitPerf 提供两类 Timer:ConstantTimer 和 RandomTimer 。通过为 LoadTest 提供这两类计时器,可以更真实地模仿用户负载。假如没有 Timer,所有线程城市同时启动。

清单 3 是用 ConstantTimer 实现的含 10 个模仿用户的负载测试:

清单 3. 为生成负载测试而实现的 suite 要领

public static Test  suite() {
 int users = 10;
 Timer timer = new  ConstantTimer(100);
 return new LoadTest(
 new  WidgetDAOImplTest("testCreate"),
  users, timer);
}

请留意,testCreate() 要领运行 10 次,每个线程隔断 100 毫 秒启动。未设按时间限制 —— 这些要领完整运行,假如个中任何的 要领执行失败,JUnit 会相应地陈诉失败。

#p#副标题#e#

用样式举办装饰

装饰 器并不范围于单个的装饰物。譬喻,在 Java™ I/O 中,可觉得 FileInputStream 装饰上一个带 BufferedReader 的 InputStreamReader(只要 记着:BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("infilename"), "UTF8")))。

装饰可以有多个条理,JUnitPerf 的 TimedTest 和 LoadTest 也是一样。当 这两个类互相装饰时,将导致一些强制的测试场景,譬喻像这样的场景:在一项 业务中安排了负载并应用了时间限制。可能,我们可以仅仅将之前的两个测试场 景以如下方法团结起来:

在 testCreate() 要领中安排一项负载。

划定每个线程必需在该时间限制内竣事。

我通过为一个尺度 Test 装饰上 LoadTest(由 TimedTest 装饰)应用了上述类型,清单 4 显示了 其功效。

清单 4. 经装饰的负载和时限测试

public static  Test suite() {
 int users = 10;
 Timer timer = new  ConstantTimer(100);
 long maxElapsedTime = 2000;
  return new TimedTest(new LoadTest(
  new WidgetDAOImplTest ("testCreate"), users, timer),
   maxElapsedTime);
}

正如您所看到的那样,testCreate() 要领运行 10 次(每隔 100 毫秒启动 一个线程),且每个线程必需在 2 秒内完成,不然整个测试场景将失败。

利用留意

尽量 JUnitPerf 是一本机能测试框架,但也要先大抵预计一下测试要设定的 机能指数。这是由于所有由 JUnitPerf 装饰的测试都通过 JUnit 框架运行,所 以就存在特另外耗损,出格是在操作 fixture 时。由于 JUnit 自己用一个 setUp 和一个 tearDown() 要领装饰所有测试样例,所以要在测试场景的整个上 下文中思量执行时间。

相应地,我常常建设利用我想要的 fixture 逻辑的测试,但也会运行一个空 白测试来确定机能指数基线。这是一个大抵的预计,但它必需作为基线添加到任 何想要的测试限制中。

譬喻,假如运行一个由 fixture 逻辑(利用 DbUnit)装饰的空缺测试用时 2.5 秒,那么您想要的所有测试限制都应将这一特别时间思量在内 —— 这可以 从清单 5 中的基准测试中看到:

清单 5. JUnitPerf 基准测试

public class  DBUnitSetUpBenchmarkTest extends DatabaseTestCase {
  private WidgetDAO dao = null;

  public void testNothing(){
  //should be about 2.5 seconds
  }

  protected IDatabaseConnection getConnection() throws  Exception {
  Class driverClass = Class.forName ("org.hsqldb.jdbcDriver");
  Connection jdbcConnection =
   DriverManager.getConnection(
    "jdbc:hsqldb:hsql://127.0.0.1", "sa", "");
  return new DatabaseConnection(jdbcConnection);
  }

  protected IDataSet getDataSet() throws Exception {
  return new FlatXmlDataSet(new File("test/conf/seed.xml"));
  }

  protected void setUp() throws Exception {
  super.setUp();
  final ApplicationContext context =
   new ClassPathXmlApplicationContext("spring-config.xml");
  this.dao = (WidgetDAO) context.getBean("widgetDAO");
  }
}

#p#分页标题#e#

请留意,清单 5 的测试样例 testNothing() 什么都没做。其惟一的目标是 确定运行 setUp() 要领(虽然,该要领也通过 DbUnit 配置了一个数据库)的 总时间。

也请记着,测试时间将依赖于呆板的设置而变革,同时也依赖于在执行 JUnitPerf 测试时运行的对象而变革。我常常发明,将 JUnitPerf 测试放到它 们本身的分类中有助于将它们同尺度测试隔分开。这意味着,在运行一个测试时 不必每次都运行 JUnitPerf 测试,譬喻在一个 CI 情况中签入代码。我也会创 建特定的 Ant 任务,从而只在经心筹谋的将机能测试思量在内的场景或情况中 运行这些测试。

试试吧!

用 JUnitPerf 举办机能测试无疑是一门严格的科学,但在开产生命周期的早 期,这是确定和监控应用措施代码的低端机能的极佳方法。别的,由于它是一个 基于装饰器的 JUnit 扩展框架,所以可以很容易地用 JUnitPerf 装饰现有的 JUnit 测试。

想想您已经花了这么多时间来担忧应用措施在负载下会奈何执行。用 JUnitPerf 举办机能测试可觉得您淘汰担心并节减时间,同时也确保了应用措施 代码的质量。

 

    关键字:

天才代写-代写联系方式