系统测试集成测试单元测试_单元和集成测试的代码覆盖率
系統(tǒng)測(cè)試集成測(cè)試單元測(cè)試
我最近在一個(gè)寵物項(xiàng)目中著手構(gòu)建自動(dòng)化的UI(集成)測(cè)試以及普通的單元測(cè)試。 我想將所有這些集成到我的Maven構(gòu)建中,并提供代碼覆蓋率報(bào)告,以便我可以了解測(cè)試覆蓋率不足的區(qū)域。 我不僅發(fā)布了項(xiàng)目的源代碼,還整理了一個(gè)簡(jiǎn)單的示例來演示如何獲得所有這些設(shè)置。 因此,如果您希望集成maven , junit , webdriver (現(xiàn)在為selenium)和emma ,請(qǐng)繼續(xù)閱讀以了解我的工作方式。首先,所有的源代碼都可以在github上找到: https : //github.com/activelylazy/coverage-example 。 我將顯示關(guān)鍵片段,但是顯然有很多細(xì)節(jié)被忽略了(希望如此)不相關(guān)。
示例應(yīng)用
該示例應(yīng)用程序不是打破傳統(tǒng),而是一個(gè)簡(jiǎn)單的,即使有點(diǎn)人為的問候世界:
這個(gè)怎么運(yùn)作
起始頁(yè)面是指向hello world頁(yè)面的簡(jiǎn)單鏈接:
<h1>Example app</h1> <p>See the <a id="messageLink" href="helloWorld.html">message</a></p>Hello World頁(yè)面僅顯示以下消息:
<h1>Example app</h1> <p id="message"><c:out value="${message}"/></p>hello world控制器渲染視圖,并傳遞消息:
public class HelloWorldController extends ParameterizableViewController {// Our message factoryprivate MessageFactory messageFactory;@Overrideprotected ModelAndView handleRequestInternal(HttpServletRequest request,HttpServletResponse response) throws Exception {// Get the success viewModelAndView mav = super.handleRequestInternal(request, response);// Add our messagemav.addObject("message",messageFactory.createMessage());return mav;}@Autowiredpublic void setMessageFactory(MessageFactory messageFactory) {this.messageFactory = messageFactory;} }最后,MessageFactory僅返回硬編碼的消息:
public String createMessage() {return "Hello world"; }單元測(cè)試
我們定義了一個(gè)簡(jiǎn)單的單元測(cè)試,以驗(yàn)證MessageFactory的行為是否符合預(yù)期:
public class MessageFactoryTest {// The message factoryprivate MessageFactory messageFactory;@Testpublic void testCreateMessage() {assertEquals("Hello world",messageFactory.createMessage());}@Autowiredpublic void setMessageFactory(MessageFactory messageFactory) {this.messageFactory = messageFactory;} }建立
一個(gè)基本的maven pom文件足以構(gòu)建此文件并運(yùn)行單元測(cè)試。 至此,我們有了一個(gè)正在運(yùn)行的應(yīng)用程序,并對(duì)我們可以構(gòu)建和運(yùn)行的核心功能(例如它)進(jìn)行了單元測(cè)試。
<project><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>helloworld</artifactId><packaging>war</packaging><version>1.0-SNAPSHOT</version><name>helloworld Maven Webapp</name><build><finalName>helloworld</finalName></build><dependencies>...omitted...</dependencies> </project>代碼覆蓋率
現(xiàn)在,我們集成Emma,以便獲得一些代碼覆蓋率報(bào)告。 首先,我們定義一個(gè)新的Maven配置文件,這使我們可以控制是否在任何給定的版本上使用emma。
<profile><id>with-emma</id><build><plugins><plugin><groupId>org.codehaus.mojo</groupId><artifactId>emma-maven-plugin</artifactId><inherited>true</inherited><executions><execution><id>instrument</id><phase>process-test-classes</phase><goals><goal>instrument</goal></goals></execution></executions></plugin></plugins></build> </profile>這只是在Maven“過程測(cè)試類”階段調(diào)用“儀器”目標(biāo)。 即,一旦我們編譯了類文件,請(qǐng)使用emma對(duì)其進(jìn)行檢測(cè)。 我們可以通過使用新的配置文件調(diào)用Maven來運(yùn)行它:
mvn clean install -Pwith-emma 構(gòu)建完成后,我們可以運(yùn)行Emma生成代碼覆蓋率報(bào)告:
在Windows上:
在Linux上:
java -cp ~/.m2/repository/emma/emma/2.0.5312/emma-2.0.5312.jar emma report -r xml,html -in coverage.ec -in target/coverage.em現(xiàn)在,我們可以在coverage / index.html中查看HTML覆蓋率報(bào)告。 此時(shí),它表明我們有50%的測(cè)試覆蓋率(按類)。 MessageFactory已完全覆蓋,但是HelloWorldController根本沒有任何測(cè)試。
整合測(cè)試
為了測(cè)試控制器和JSP,我們將使用WebDriver創(chuàng)建一個(gè)簡(jiǎn)單的集成測(cè)試。 這是一個(gè)恰巧啟動(dòng)瀏覽器的JUnit測(cè)試。
public class HelloWorldIntegrationTest {// The webdriverprivate static WebDriver driver;@BeforeClasspublic static void initWebDriver() {driver = new FirefoxDriver();}@AfterClasspublic static void stopSeleniumClent() {try {driver.close();driver.quit();} catch( Throwable t ) {// Catch error & log, not critical for testsSystem.err.println("Error stopping driver: "+t.getMessage());t.printStackTrace(System.err);}}@Testpublic void testHelloWorld() {// Start from the homepagedriver.get("http://localhost:9080/helloworld/");HomePage homePage = new HomePage(driver);HelloWorldPage helloWorldPage = homePage.clickMessageLink();assertEquals("Hello world",helloWorldPage.getMessage());} } 第4-18行只是在測(cè)試之前啟動(dòng)Web驅(qū)動(dòng)程序,并在測(cè)試完成后將其關(guān)閉(關(guān)閉瀏覽器窗口)。
在第22行,我們使用硬編碼的URL導(dǎo)航到主頁(yè)。
在第23行,我們初始化主頁(yè)的Web Driver 頁(yè)面對(duì)象 。 這封裝了頁(yè)面工作方式的所有細(xì)節(jié),從而使測(cè)試可以與頁(yè)面進(jìn)行功能上的交互,而無需擔(dān)心機(jī)制(使用哪些元素等)。 在第24行,我們使用主頁(yè)對(duì)象單擊“消息”鏈接; 這將導(dǎo)航到hello world頁(yè)面。 在第25行,我們確認(rèn)hello world頁(yè)面上顯示的消息是我們所期望的。 注意:我正在使用頁(yè)面對(duì)象來將測(cè)試規(guī)范 (做什么)與測(cè)試實(shí)現(xiàn) (如何做到)分開。 有關(guān)為什么這很重要的更多信息,請(qǐng)參見防止測(cè)試變脆 。
主頁(yè)
主頁(yè)對(duì)象非常簡(jiǎn)單:
public HelloWorldPage clickMessageLink() {driver.findElement(By.id("messageLink")).click();return new HelloWorldPage(driver); }HelloWorldPage
hello world頁(yè)面同樣簡(jiǎn)單:
public String getMessage() {return driver.findElement(By.id("message")).getText(); }運(yùn)行集成測(cè)試
要在我們的Maven構(gòu)建過程中運(yùn)行集成測(cè)試,我們需要進(jìn)行一些更改。 首先,我們需要從單元測(cè)試階段中排除集成測(cè)試:
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId>...<configuration>...<excludes><exclude>**/*IntegrationTest.java</exclude><exclude>**/common/*</exclude></excludes></configuration> </plugin>然后,我們定義一個(gè)新的配置文件,因此我們可以選擇運(yùn)行集成測(cè)試:
<profile><id>with-integration-tests</id><build><plugins><plugin><groupId>org.mortbay.jetty</groupId><artifactId>maven-jetty-plugin</artifactId><version>6.1.22</version><configuration><scanIntervalSeconds>5</scanIntervalSeconds><stopPort>9966</stopPort><stopKey>foo</stopKey><connectors><connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"><port>9080</port><maxIdleTime>60000</maxIdleTime></connector></connectors></configuration><executions><execution><id>start-jetty</id><phase>pre-integration-test</phase><goals><goal>run</goal></goals><configuration><daemon>true</daemon></configuration></execution><execution><id>stop-jetty</id><phase>post-integration-test</phase><goals><goal>stop</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.5</version><inherited>true</inherited><executions><execution><id>integration-tests</id><phase>integration-test</phase><goals><goal>test</goal></goals><configuration><excludes><exclude>**/common/*</exclude></excludes><includes><include>**/*IntegrationTest.java</include></includes></configuration></execution></executions></plugin></plugins></build> </profile> <個(gè)人資料><id> with-integration-tests </ id>
<內(nèi)部版本>
<插件>
<插件>
<groupId> org.mortbay.jetty </ groupId>
<artifactId> maven-jetty-plugin </ artifactId>
<version> 6.1.22 </ version>
<配置>
<scanIntervalSeconds> 5 </ scanIntervalSeconds>
<stopPort> 9966 </ stopPort>
<stopKey> foo </ stopKey>
<連接器>
<連接器實(shí)現(xiàn)=” org.mortbay.jetty.nio.SelectChannelConnector”>
<port> $ {test.server.port} </ port>
<maxIdleTime> 60000 </ maxIdleTime>
</ connector>
</ connectors>
</ configuration>
<執(zhí)行>
<執(zhí)行>
<id> start-jetty </ id>
<phase>集成前測(cè)試</ phase>
<目標(biāo)>
<goal>運(yùn)行</ goal>
</ goals>
<配置>
<daemon> true </ daemon>
</ configuration>
</ execution>
<執(zhí)行>
<id>停止碼頭</ id>
<phase>集成后測(cè)試</ phase>
<目標(biāo)>
<goal>停止</ goal>
</ goals>
</ execution>
</ executions>
</ plugin>
<插件>
<groupId> org.apache.maven.plugins </ groupId>
<artifactId> maven-surefire-plugin </ artifactId>
<version> 2.5 </ version>
<inherited> true </ inherited>
<執(zhí)行>
<執(zhí)行>
<id>集成測(cè)試</ id>
<phase>集成測(cè)試</ phase>
<目標(biāo)>
<goal>測(cè)試</ goal>
</ goals>
<配置>
<排除>
<exclude> ** / common / * </ exclude>
</ excludes>
<包括>
<include> ** / * IntegrationTest.java </ include>
</ includes>
</ configuration>
</ execution>
</ executions>
</ plugin>
</ plugins>
</ build>
</ profile>
這可能看起來很復(fù)雜,但實(shí)際上我們只是在配置碼頭來運(yùn)行我們的集成測(cè)試。 然后配置如何自行運(yùn)行集成測(cè)試。
在9-19行中,配置碼頭-要繼續(xù)運(yùn)行的港口以及如何停止碼頭。
21-30行配置了碼頭,以在Maven構(gòu)建的“集成前測(cè)試”階段運(yùn)行。 31-37行配置了要在Maven構(gòu)建的“集成后測(cè)試”階段停止的碼頭。 在第40-62行中,我們?cè)俅问褂昧薽aven-surefire-plugin,這次是在構(gòu)建的“集成測(cè)試”階段運(yùn)行,僅運(yùn)行我們的集成測(cè)試類。
我們可以使用以下命令運(yùn)行此構(gòu)建:
mvn clean install -Pwith-emma -Pwith-integration-tests這將構(gòu)建所有內(nèi)容,運(yùn)行單元測(cè)試,構(gòu)建戰(zhàn)爭(zhēng),啟動(dòng)碼頭進(jìn)行戰(zhàn)爭(zhēng),運(yùn)行我們的集成測(cè)試(運(yùn)行其余部分時(shí),您將看到一個(gè)firefox窗口彈出),然后關(guān)閉碼頭。 由于戰(zhàn)爭(zhēng)是通過檢測(cè)類構(gòu)建的,因此在運(yùn)行集成測(cè)試時(shí),Emma還會(huì)跟蹤代碼覆蓋率。
現(xiàn)在,我們可以構(gòu)建應(yīng)用程序,運(yùn)行單元測(cè)試和集成測(cè)試,收集組合的代碼覆蓋率報(bào)告。 如果我們重新運(yùn)行emma報(bào)告并檢查代碼覆蓋率,我們現(xiàn)在將看到100%的測(cè)試覆蓋率-因?yàn)榭刂破饕餐ㄟ^測(cè)試覆蓋。
問題
有哪些未解決的問題,可以做哪些進(jìn)一步的擴(kuò)展?
- 該構(gòu)建會(huì)生成一個(gè)已檢測(cè)到的WAR –這意味著您需要運(yùn)行第二個(gè)構(gòu)建(沒有emma)才能獲得可用于生產(chǎn)的構(gòu)建。
- 集成測(cè)試對(duì)Jetty配置為啟動(dòng)的端口進(jìn)行硬編碼。 意味著測(cè)試不能直接在Eclipse中運(yùn)行。 可以傳入此端口,默認(rèn)為8080,這樣集成測(cè)試就可以通過maven構(gòu)建在Eclipse中運(yùn)行。
- 在構(gòu)建服務(wù)器上運(yùn)行時(shí),您可能不希望Firefox隨機(jī)彈出(如果甚至安裝了X)。 因此,運(yùn)行xvfb是一個(gè)好主意。 可以將maven設(shè)置為在集成測(cè)試之前和之后啟動(dòng)和停止xvfb。
參考: 單元和集成測(cè)試的代碼覆蓋范圍以及Actively Lazy博客的JCG合作伙伴 Dave提供的信息
相關(guān)文章 :- 任何軟件開發(fā)公司應(yīng)存在的服務(wù),實(shí)踐和工具,第1部分
- 任何軟件開發(fā)公司應(yīng)存在的服務(wù),實(shí)踐和工具,第2部分
- 這是在您的業(yè)務(wù)邏輯之前!
- 您的代碼中有幾個(gè)錯(cuò)誤?
- 使用FindBugs產(chǎn)生更少的錯(cuò)誤代碼
- Java工具:源代碼優(yōu)化和分析
- 每個(gè)程序員都應(yīng)該知道的事情
- 為什么自動(dòng)化測(cè)試可以提高您的開發(fā)速度
翻譯自: https://www.javacodegeeks.com/2011/10/code-coverage-with-unit-integration.html
系統(tǒng)測(cè)試集成測(cè)試單元測(cè)試
總結(jié)
以上是生活随笔為你收集整理的系统测试集成测试单元测试_单元和集成测试的代码覆盖率的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓好平板推荐(安卓好平板)
- 下一篇: JDK 9:模块系统状态的重点