我在我的項目中使用JUnit4和Hibernate3。 Hibernate依賴於Slf4j,因此我的項目也包含這個庫。現在我想在單元測試中使用Slf4j以記錄補充測試信息。您能否提供一個簡單的示例,說明我的單元測試應該如何才能記錄一行文本?在多次測試中,最好是沒有代碼重複。在單元測試中是否有任何slf4j用法的簡單模式?
回答
我也喜歡用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並不重要。
爲什麼你想在單元測試中記錄東西?單元測試應該是合格/不合格,並且應該使用測試框架來表明這一點。您不想通過輸出來閱讀測試是否通過或失敗。如果它失敗了,那麼在IDE /調試器中運行它是修復它的最好方法。
因爲它有時可以用來了解測試失敗的原因,或者打印性能指標,以防您隨意關注這些測試。 – BjornS 2010-09-29 11:43:50
如果您想進行性能測試,請正確執行並捕獲並繪製數字。隨便看看UT跑步中的一些數字並不是衡量表現的方法。至於爲什麼一個測試失敗,你應該寫你的斷言,所以文本告訴你出了什麼問題。在工作中,我們的產品有數萬個單元測試;如果我們必須閱讀那些輸出結果,你認爲我們會在哪裏? – dty 2010-09-29 11:47:13
我沒有說性能測試,我只是說隨便跟蹤它作爲你爲什麼要登錄你的測試的例子。至於你的工作,是的,我們也有數以萬計的測試,你會驚訝地發現你想要的信息與特定測試有關。此外,除非你真的需要,而且當你真的需要的時候,你不需要閱讀它們,它的方便已經有日誌了。 – BjornS 2010-09-29 11:52:52
這對我來說似乎是一種難聞的氣味。
您應該始終避免手動檢查或單元測試驗證。
單元測試應該是自動化的,如果你的構建工具告訴你,某些測試失敗應該只需要人工干預,並應使用所有這些驗證方法(如的assertEquals)
當然可以。 OP想知道代碼*應該看起來像做什麼,我們中的許多人都建議不要存在代碼。這就是它*應該如何。 – iX3 2015-02-03 14:45:16
有趣的是,dyt的另一個答案基本上是說類似的東西(人們應該避免因爲blablabla而在單元測試中登錄)。我的回答是收到更多的讚譽。 LOL – 2015-11-24 07:00:51
在測試期間記錄通常是非常寶貴的,特別是當測試失敗時。當測試通過或日誌變得不可讀時,這當然需要與過多的日誌記錄進行平衡。 – AntonPiatek 2017-12-14 15:51:40
我們使用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中,但只有在捕獲錯誤時纔將其轉儲到文件;有點像時間旅行:)
我需要在'@ Before'註釋的方法內的每個單元測試中執行'getLogger()',對吧? – yegor256 2010-09-29 14:12:49
不,只是私有靜態引用,那麼你可以簡單地調用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
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();
}
這只是工作,但它需要在每單元測試這是一種痛苦被投入。 。
另一種解決方案是將日誌記錄實現切換爲僅用於測試的簡單實現。
所以在你的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只是默認記錄一切標準錯誤,並且不需要任何配置文件
SimpleLogger默認日誌級別是INFO。例如,要將其更改爲DEBUG,請使用JVM選項 -Dorg.slf4j.simpleLogger.defaultLogLevel = DEBUG – 2017-10-25 15:31:54
添加日誌記錄在寫新的測試是非常有用的。與此同時,當測試在CI或CD管道中運行時,您希望禁用日誌記錄(或者至少不要冗長)。有時候故障是暫時的,特別是在端到端的運行中,所以在CI作業的控制檯日誌上輸出相關的輸出是有幫助的。這篇文章很好地描述了它 - https://gualtierotesta.wordpress.com/2015/11/01/tutorial-logging-during-tests/
- 1. 單元測試 - 是否有單元測試調用其他單元測試的不良形式
- 2. 是否可以在調試模式下運行單元測試?
- 3. 單元測試的目的不是簡單的真相測試
- 4. 單元測試模式
- 5. 在Visual Studio 2012單元測試中是否有可用於.runsettings文件的任何xsd模式?
- 6. 單元測試(是或否)
- 7. 單元測試模擬法
- 8. 特質所有者在單元測試中是否有用?
- 9. Rascal是否有單元測試框架?
- 10. 如何測試是否在單元測試中出現異常
- 11. NHibernate如何使單元測試簡單?
- 12. 檢測是否有任何單元格正在JTable中編輯
- 13. Android單元測試測試是否在onCreate()中調用了setContentView()
- 14. 如何檢測單元測試是否調用某個方法?
- 15. 在單元測試的所有方法是否委託檢查
- 16. Simple單元測試簡單單元測試
- 17. 測試單元測試是否存在保存方法
- 18. 單元測試,如何檢查$ uibModal的模板是否存在
- 19. 如何在單元測試簡單方法時引發異常
- 20. ASP.NET單元測試 - 是否有指定所需屬性的簡寫方式?
- 21. 測試iFrame的location.href是否在jasmine單元測試中設置
- 22. 單元測試單例模式方法__clone()在PHP
- 23. 單元測試是否意味着測試必須被模擬?
- 24. 是否有任何機構在ASIHttpRequest上有簡單的應用
- 25. 簡單的haskell單元測試
- 26. 簡單的android單元測試失敗
- 27. Javascript單元測試茉莉花/單元測試 - 我如何測試一個私有函數是否被調用?
- 28. C#單元測試簡介
- 29. 如何測試函數是否被調用(單元測試角)
- 30. 簡單的方法來測試元素是否在前面?在一個頁面
爲避免代碼重複,您可以將導入和「Logger」聲明移至抽象的「TestCase」子類。 – 2012-11-12 21:34:46