/*************************GO-LICENSE-START********************************* * Copyright 2014 ThoughtWorks, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *************************GO-LICENSE-END***********************************/ package com.thoughtworks.go.domain; import java.io.*; import java.util.UUID; import com.thoughtworks.go.domain.exception.ArtifactPublishingException; import com.thoughtworks.go.util.ClassMockery; import com.thoughtworks.go.util.FileUtil; import com.thoughtworks.go.util.TestFileUtil; import com.thoughtworks.go.work.DefaultGoPublisher; import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.integration.junit4.JMock; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.core.io.ClassPathResource; import static com.thoughtworks.go.domain.UnitTestReportGenerator.FAILED_TEST_COUNT; import static com.thoughtworks.go.domain.UnitTestReportGenerator.IGNORED_TEST_COUNT; import static com.thoughtworks.go.domain.UnitTestReportGenerator.TEST_TIME; import static com.thoughtworks.go.domain.UnitTestReportGenerator.TOTAL_TEST_COUNT; import static com.thoughtworks.go.util.TestUtils.copyAndClose; import static com.thoughtworks.go.util.TestUtils.restoreConsoleOutput; import static com.thoughtworks.go.util.TestUtils.suppressConsoleOutput; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; @RunWith(JMock.class) public class UnitTestReportGeneratorTest { private final Mockery context = new ClassMockery(); private File testFolder; private UnitTestReportGenerator generator; private DefaultGoPublisher publisher; @Before public void setUp() { testFolder = TestFileUtil.createTempFolder(UUID.randomUUID().toString()); publisher = context.mock(DefaultGoPublisher.class); generator = new UnitTestReportGenerator(publisher, testFolder); } @After public void tearDown() { FileUtil.deleteFolder(testFolder); } @Test public void shouldGenerateReportForNUnit() throws IOException, ArtifactPublishingException { context.checking(new Expectations() { { one(publisher).upload(with(any(File.class)), with(any(String.class))); one(publisher).setProperty(new Property(TOTAL_TEST_COUNT, "206")); one(publisher).setProperty(new Property(FAILED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(IGNORED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(TEST_TIME, "NaN")); } }); copyAndClose(source("TestResult.xml"), target("test-result.xml")); final Properties properties = generator.generate(testFolder.listFiles(), "testoutput"); assertThat(testFolder.listFiles().length, is(2)); } @Test public void shouldGenerateReportForNUnitXmlWithByteOrderMark() throws IOException, ArtifactPublishingException { context.checking(new Expectations() { { one(publisher).upload(with(any(File.class)), with(any(String.class))); one(publisher).setProperty(new Property(TOTAL_TEST_COUNT, "18")); one(publisher).setProperty(new Property(FAILED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(IGNORED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(TEST_TIME, "1.570")); } }); copyAndClose(source("NunitTestResultWithByteOrderMark.xml"), target("test-result.xml")); generator.generate(testFolder.listFiles(), "testoutput"); assertThat(testFolder.listFiles().length, is(2)); } @Test public void shouldNotGenerateAnyReportIfNoTestResultsWereFound() throws IOException, ArtifactPublishingException { expectZeroedProperties(); suppressConsoleOutput(); generator.generate(testFolder.listFiles(), "testoutput"); restoreConsoleOutput(); } @Test public void shouldNotGenerateAnyReportIfTestResultIsEmpty() throws IOException, ArtifactPublishingException { context.checking(new Expectations() { { one(publisher).consumeLine("Ignoring file empty.xml - it is not a recognised test file."); one(publisher).setProperty(new Property(TOTAL_TEST_COUNT, "0")); one(publisher).setProperty(new Property(FAILED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(IGNORED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(TEST_TIME, "0.000")); one(publisher).upload(with(any(File.class)), with(any(String.class))); } }); copyAndClose(source("empty.xml"), target("empty.xml")); suppressConsoleOutput(); generator.generate(testFolder.listFiles(), "testoutput"); restoreConsoleOutput(); } private void expectZeroedProperties() throws ArtifactPublishingException { context.checking(new Expectations() { { one(publisher).upload(with(any(File.class)), with(any(String.class))); one(publisher).setProperty(new Property(TOTAL_TEST_COUNT, "0")); one(publisher).setProperty(new Property(FAILED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(IGNORED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(TEST_TIME, "0.000")); } }); } @Test public void shouldNotGenerateAnyReportIfTestReportIsInvalid() throws IOException, ArtifactPublishingException { context.checking(new Expectations() { { one(publisher).consumeLine("Ignoring file Invalid.xml - it is not a recognised test file."); one(publisher).setProperty(new Property(TOTAL_TEST_COUNT, "0")); one(publisher).setProperty(new Property(FAILED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(IGNORED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(TEST_TIME, "0.000")); one(publisher).upload(with(any(File.class)), with(any(String.class))); } }); copyAndClose(source("InvalidTestResult.xml"), target("Invalid.xml")); suppressConsoleOutput(); generator.generate(testFolder.listFiles(), "testoutput"); restoreConsoleOutput(); } //This is bug #2319 @Test public void shouldStillUploadResultsIfReportIsIllegalBug2319() throws IOException, ArtifactPublishingException { context.checking(new Expectations() { { one(publisher).consumeLine("Ignoring file Coverage.xml - it is not a recognised test file."); one(publisher).upload(with(any(File.class)), with(any(String.class))); one(publisher).setProperty(new Property(TOTAL_TEST_COUNT, "0")); one(publisher).setProperty(new Property(FAILED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(IGNORED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(TEST_TIME, "0.000")); } }); copyAndClose(source("xml_samples/Coverage.xml"), target("Coverage.xml")); suppressConsoleOutput(); generator.generate(testFolder.listFiles(), "testoutput"); restoreConsoleOutput(); } @Test public void shouldGenerateReportForJUnitAlso() throws IOException, ArtifactPublishingException { context.checking(new Expectations() { { one(publisher).upload(with(any(File.class)), with(any(String.class))); one(publisher).setProperty(new Property(TOTAL_TEST_COUNT, "1")); one(publisher).setProperty(new Property(FAILED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(IGNORED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(TEST_TIME, "0.456")); } }); copyAndClose(source("SerializableProjectConfigUtilTest.xml"), target("AgentTest.xml")); generator.generate(testFolder.listFiles(), "testoutput"); } @Test public void shouldGenerateReportForJUnitWithMultipleFiles() throws IOException, ArtifactPublishingException { context.checking(new Expectations() { { one(publisher).upload(with(any(File.class)), with(any(String.class))); one(publisher).setProperty(new Property(TOTAL_TEST_COUNT, "5")); one(publisher).setProperty(new Property(FAILED_TEST_COUNT, "3")); one(publisher).setProperty(new Property(IGNORED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(TEST_TIME, "1.286")); } }); copyAndClose(source("UnitTestReportGeneratorTest.xml"), target("UnitTestReportGeneratorTest.xml")); copyAndClose(source("SerializableProjectConfigUtilTest.xml"), target("SerializableProjectConfigUtilTest.xml")); generator.generate(testFolder.listFiles(), "testoutput"); } @Test public void shouldGenerateReportForNUnitGivenMutipleInputFiles() throws IOException, ArtifactPublishingException { context.checking(new Expectations() { { one(publisher).upload(with(any(File.class)), with(any(String.class))); one(publisher).setProperty(new Property(TOTAL_TEST_COUNT, "2762")); one(publisher).setProperty(new Property(FAILED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(IGNORED_TEST_COUNT, "120")); one(publisher).setProperty(new Property(TEST_TIME, "221.766")); } }); copyAndClose(source("TestReport-Integration.xml"), target("test-result1.xml")); copyAndClose(source("TestReport-Unit.xml"), target("test-result2.xml")); generator.generate(testFolder.listFiles(), "testoutput"); } @Test public void shouldGenerateReportForXmlFilesRecursivelyInAFolder() throws ArtifactPublishingException, IOException { context.checking(new Expectations() { { one(publisher).consumeLine("Ignoring file Coverage.xml - it is not a recognised test file."); one(publisher).upload(with(any(File.class)), with(any(String.class))); one(publisher).setProperty(new Property(TOTAL_TEST_COUNT, "204")); one(publisher).setProperty(new Property(FAILED_TEST_COUNT, "0")); one(publisher).setProperty(new Property(IGNORED_TEST_COUNT, "6")); one(publisher).setProperty(new Property(TEST_TIME, "80.231")); } }); File reports = new File(testFolder.getAbsoluteFile(), "reports"); reports.mkdir(); File module = new File(reports, "module"); module.mkdir(); copyAndClose(source("xml_samples/Coverage.xml"), target("reports/module/Coverage.xml")); copyAndClose(source("xml_samples/TestResult.xml"), target("reports/TestResult.xml")); suppressConsoleOutput(); generator.generate(testFolder.listFiles(), "testoutput"); restoreConsoleOutput(); } private OutputStream target(String targetFile) throws FileNotFoundException { return new FileOutputStream(testFolder.getAbsolutePath() + FileUtil.fileseparator() + targetFile); } private InputStream source(String filename) throws IOException { return new ClassPathResource(FileUtil.fileseparator() + "data" + FileUtil.fileseparator() + filename).getInputStream(); } }