2010-09-29 20 views
13

我在我的項目中使用JUnit4和Hibernate3。 Hibernate依賴於Slf4j,因此我的項目也包含這個庫。現在我想在單元測試中使用Slf4j以記錄補充測試信息。您能否提供一個簡單的示例,說明我的單元測試應該如何才能記錄一行文本?在多次測試中,最好是沒有代碼重複在單元測試中是否有任何slf4j用法的簡單模式?

回答

10

我也喜歡用SLF4J在我的JUnit測試我DAO類。它在您創建新測試或修改舊測試時確實有幫助。我通常會將我的舊日誌記錄輸出保留在調試級別,並在信息級別創建新的日誌記錄語句,同時我仍在積極研究該方法中的代碼。我的一個JUnit類的會是這個樣子:

package com.example.mydao; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
// other imports not shown... 

public class TestMyDAO extends TestCase { 

    private static final Logger logger = 
     LoggerFactory.getLogger(TestMyDAO.class); 


    public void testA() { 
     logger.debug("Logging from testA() method"); 
    } 

    public void testB() { 
     logger.debug("Logging from testB() method"); 
    } 

    public void testThatIAmWorkingOn() { 
     logger.info("Logging from my new test method at INFO level"); 
    } 

} 

我使用log4j的是實際的記錄供應商,所以我log4j.xml配置文件看起來像這樣:

<?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> 
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false"> 
    <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender"> 
     <layout class="org.apache.log4j.PatternLayout"> 
      <param name="ConversionPattern" value="%d %-5p [%c{1}] %m %n" /> 
     </layout> 
    </appender> 

    <logger name="com.example.mydao" additivity="false"> 
     <level value="INFO" /> 
     <appender-ref ref="consoleAppender"/> 
    </logger> 

    <logger name="org.hibernate" additivity="false"> 
     <level value="WARN" /> 
     <appender-ref ref="consoleAppender"/> 
    </logger> 

    <logger name="org.hibernate.connection.DriverManagerConnectionProvider" additivity="false"> 
     <level value="INFO" /> 
     <appender-ref ref="consoleAppender"/> 
    </logger> 

    <logger name="org.hibernate.connection.C3P0ConnectionProvider" additivity="false"> 
     <level value="INFO" /> 
     <appender-ref ref="consoleAppender"/> 
    </logger> 

    <logger name="com.mchange" additivity="false"> 
     <level value="WARN" /> 
     <appender-ref ref="consoleAppender"/> 
    </logger> 

    <logger name="com.mchange.v2.resourcepool.BasicResourcePool" additivity="false"> 
     <level value="INFO" /> 
     <appender-ref ref="consoleAppender"/> 
    </logger> 

    <logger name="com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource" additivity="false"> 
     <level value="INFO" /> 
     <appender-ref ref="consoleAppender"/> 
    </logger> 

    <logger name="com.mchange.v2.c3p0.C3P0Registry" additivity="false"> 
     <level value="INFO" /> 
     <appender-ref ref="consoleAppender"/> 
    </logger> 

    <root> 
     <priority value ="WARN" /> 
     <appender-ref ref="consoleAppender"/> 
    </root> 

</log4j:configuration> 

這給了我的信息從我的JUnit類輸出,以及Hibernate運行時和Hibernate使用的其他庫中的一些有用的東西。根據自己的口味調整。

最後,我需要確保所有的下列庫都在我的類路徑中,當我執行JUnit測試:

  • slf4j-api-1.6.0.jar
  • slf4j-log4j12-1.6.0.jar
  • log4j-1.2.16.jar
  • log4j.xml(我的配置文件,如上所示)
  • 某些版本的JUnit運行時JAR
  • 在生產中運行應用程序時,通常存在的所有JAR

這就是我在使用log4j時所做的。如果您使用不同的日誌記錄實施,則相應地進行調整。只要「API」和實現JAR是相同版本(我的版本都是1.6.0),使用不同版本的slf4j並不重要。

+0

爲避免代碼重複,您可以將導入和「Logger」聲明移至抽象的「TestCase」子類。 – 2012-11-12 21:34:46

11

爲什麼你想在單元測試中記錄東西?單元測試應該是合格/不合格,並且應該使用測試框架來表明這一點。您不想通過輸出來閱讀測試是否通過或失敗。如果它失敗了,那麼在IDE /調試器中運行它是修復它的最好方法。

+11

因爲它有時可以用來了解測試失敗的原因,或者打印性能指標,以防您隨意關注這些測試。 – BjornS 2010-09-29 11:43:50

+6

如果您想進行性能測試,請正確執行並捕獲並繪製數字。隨便看看UT跑步中的一些數字並不是衡量表現的方法。至於爲什麼一個測試失敗,你應該寫你的斷言,所以文本告訴你出了什麼問題。在工作中,我們的產品有數萬個單元測試;如果我們必須閱讀那些輸出結果,你認爲我們會在哪裏? – dty 2010-09-29 11:47:13

+2

我沒有說性能測試,我只是說隨便跟蹤它作爲你爲什麼要登錄你的測試的例子。至於你的工作,是的,我們也有數以萬計的測試,你會驚訝地發現你想要的信息與特定測試有關。此外,除非你真的需要,而且當你真的需要的時候,你不需要閱讀它們,它的方便已經有日誌了。 – BjornS 2010-09-29 11:52:52

-1

這對我來說似乎是一種難聞的氣味。

您應該始終避免手動檢查或單元測試驗證。

單元測試應該是自動化的,如果你的構建工具告訴你,某些測試失敗應該只需要人工干預,並應使用所有這些驗證方法(如的assertEquals)

+2

當然可以。 OP想知道代碼*應該看起來像做什麼,我們中的許多人都建議不要存在代碼。這就是它*應該如何。 – iX3 2015-02-03 14:45:16

+0

有趣的是,dyt的另一個答案基本上是說類似的東西(人們應該避免因爲blablabla而在單元測試中登錄)。我的回答是收到更多的讚譽。 LOL – 2015-11-24 07:00:51

+0

在測試期間記錄通常是非常寶貴的,特別是當測試失敗時。當測試通過或日誌變得不可讀時,這當然需要與過多的日誌記錄進行平衡。 – AntonPiatek 2017-12-14 15:51:40

2

我們使用log4j的提供失敗的原因作爲我們的輸出記錄器;

private static Logger log = LoggerFactory.getLogger(MyClassHere.class); 

如果您正確配置它,slf4j應找到並使用log4j而不會出現問題。 爲了讓生活方便,我會用這個Eclipse的模式,因爲您將編寫這些代碼公平一點:

private static Logger log = LoggerFactory.getLogger(${enclosing_type}.class); 
${:import(org.slf4j.Logger,org.slf4j.LoggerFactory)} 

的測試中,我建議你不要超越INFO水平,並保持最事情DEBUG 。如果你真的想要智能地捕捉很多錯誤,那麼我建議你查看一下PositronLogger,它是一個日誌文件appender,它會靜靜地將所有東西都提取到TRACE中,但只有在捕獲錯誤時纔將其轉儲到文件;有點像時間旅行:)

http://github.com/andreaja/PositronLogger

+0

我需要在'@ Before'註釋的方法內的每個單元測試中執行'getLogger()',對吧? – yegor256 2010-09-29 14:12:49

+0

不,只是私有靜態引用,那麼你可以簡單地調用log.debug(「some stuff」);無論你喜歡哪裏。編輯:我應該澄清; LoggerFactory.getLogger()是靜態引用的一部分,您不需要在@Before中調用它,只需將其作爲測試類中的字段輸入即可。一個簡單的例子:class MyTests {private static Logger log = LoggerFactory.getLogger(MyTests.class); @Test public void magic(){log.info(「...」); }} – BjornS 2010-10-01 08:26:45

0

Slf4j是一個日誌門面,您可以在運行時決定實現。 Slf4j只是一個API。例如,你可以使用log4j作爲底層實現。你需要在你的pom.xml中包含兩個依賴。

<!-- Depend on slf4j API --> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-api</artifactId> 
     <version>1.7.12</version> 
    </dependency> 
    <!-- Use log4j as the slf4j implementation --> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-log4j12</artifactId> 
     <version>1.7.12</version> 
    </dependency> 

的事情是,運行在IDE或通過mvn test單元測試時,它可以是惱人設置log4j的配置。尤其是以一種不需要做任何事情的方式工作。除非在類路徑上有一個log4j.properties文件或者設置了-Dlog4j.configuration=file:///path/to/log4j.properties,否則Log4j默認拒絕記錄任何內容。

一種解決方案是把在單元測試,代碼設置log4j的配置編程:

@BeforeClass 
    public static void beforeClass() { 
     BasicConfigurator.resetConfiguration(); 
     BasicConfigurator.configure(); 
    } 

這只是工作,但它需要在單元測試這是一種痛苦被投入。 。

5

另一種解決方案是將日誌記錄實現切換爲僅用於測試的簡單實現。

所以在你的pom.xml

<!-- Depend on slf4j API --> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-api</artifactId> 
     <version>1.7.12</version> 
    </dependency> 

    <!-- Use SimpleLogger as the slf4j implementation in test --> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-simple</artifactId> 
     <version>1.7.12</version> 
     <scope>test</scope> 
    </dependency> 

    <!-- Use log4j as the slf4j implementation during runtime (not test) --> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-log4j12</artifactId> 
     <version>1.7.12</version> 
     <scope>runtime</scope> 
    </dependency> 

的SimpleLogger只是默認記錄一切標準錯誤,並且不需要任何配置文件

+1

SimpleLogger默認日誌級別是INFO。例如,要將其更改爲DEBUG,請使用JVM選項 -Dorg.slf4j.simpleLogger.defaultLogLevel = DEBUG – 2017-10-25 15:31:54

相關問題