Skip to content

Commit

Permalink
Merge pull request #51 from rubensousa/rethrow_error
Browse files Browse the repository at this point in the history
Catch test exceptions to write reports before instrumentation is over
  • Loading branch information
rubensousa authored Sep 27, 2024
2 parents 5eb9e73 + 30e6c06 commit 900aa3f
Show file tree
Hide file tree
Showing 21 changed files with 84 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ class AllureReportGenerator(
logcatOutputDir: File,
outputDir: File,
keepLogcatOnSuccess: Boolean,
deleteOriginalReports: Boolean
) {
val reportDir = parser.findReportDir(testResultDir) ?: return
val testReportFiles = parser.parseTestReports(reportDir)
Expand All @@ -62,9 +61,6 @@ class AllureReportGenerator(
outputDir = outputDir,
logcatFile = logcatFile
)
if (deleteOriginalReports) {
testReportFile.file.delete()
}
createContainerReport(testReportFile.report)?.let {
moveContainerReport(it, testResultDir, outputDir)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ class AllureReportPlugin : Plugin<Project> {
val testOutputDir = project.layout.buildDirectory.file(testOutputDirPath).get().asFile
val logcatOutputDir = project.layout.buildDirectory.file(logcatOutputDirPath).get().asFile
val keepLogcatOnSuccess = extension?.keepLogcatOnSuccess ?: false
val deleteOriginalReports = extension?.deleteOriginalReports ?: true
testOutputDir.mkdirs()
project.tasks.register("cleanAllureReport") {
it.group = "report"
Expand All @@ -67,9 +66,7 @@ class AllureReportPlugin : Plugin<Project> {
// Clean-up all the files from the output dirs
// to avoid conflicts with the next report generation
outputDir.deleteRecursively()
if (deleteOriginalReports) {
testOutputDir.deleteRecursively()
}
testOutputDir.deleteRecursively()
}
}

Expand All @@ -83,7 +80,6 @@ class AllureReportPlugin : Plugin<Project> {
logcatOutputDir = logcatOutputDir,
outputDir = outputDir,
keepLogcatOnSuccess = keepLogcatOnSuccess,
deleteOriginalReports = deleteOriginalReports
)
println("Allure report generated in file:///$outputDirPath")
}
Expand Down Expand Up @@ -114,12 +110,6 @@ interface AllureReportExtension {
*/
var keepLogcatOnSuccess: Boolean?

/**
* True if the original reports should be removed after the allure reports are generated
* Default: true to save space
*/
var deleteOriginalReports: Boolean?

/**
* The report output path.
* Can be used to merge reports of multiple modules by using the same directory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,44 @@ class InstrumentedReportRuleTest {
assertThat(execution.status).isEqualTo(ReportStatus.RUNNING)
}

@Test
fun testBeforeStageIsPassedToReport() {
// given
val description = testDescriptionRule.getDescription()
reportRule.start(description)
val beforeTitle = "Something"
val beforeStep = "StepBefore"

// when
reportRule.before(beforeTitle) {
step(beforeStep)
}

// then
val report = reportRule.getCurrentReport()
val beforeStage = report.getStagesBefore().first()
assertThat(beforeStage.getTitle()).isEqualTo(beforeTitle)
assertThat(beforeStage.getTestStages().first().getTitle()).isEqualTo(beforeStep)
}

@Test
fun testAfterStageIsPassedToReport() {
// given
val description = testDescriptionRule.getDescription()
reportRule.start(description)
val afterTitle = "Something"
val afterStep = "StepAfter"

// when
reportRule.after(afterTitle) {
step(afterStep)
}

// then
val report = reportRule.getCurrentReport()
val afterStage = report.getStagesAfter().first()
assertThat(afterStage.getTitle()).isEqualTo(afterTitle)
assertThat(afterStage.getTestStages().first().getTitle()).isEqualTo(afterStep)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,12 @@ open class InstrumentedReportRule internal constructor(
action: InstrumentedBlockingTest.() -> Unit,
) {
val currentTest = getCurrentTest<InstrumentedBlockingTest>()
action(currentTest)
try {
action(currentTest)
} catch (error: Throwable) {
currentTest.onFailed(error)
throw error
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.rubensousa.carioca.report.android

import com.rubensousa.carioca.report.android.storage.ReportStorageProvider
import com.rubensousa.carioca.report.runtime.StageReport
import com.rubensousa.carioca.report.runtime.TestMetadata
import java.io.OutputStream
Expand All @@ -42,7 +43,7 @@ interface InstrumentedReporter {
fun writeTestReport(
testMetadata: TestMetadata,
report: StageReport,
storageProvider: com.rubensousa.carioca.report.android.storage.ReportStorageProvider,
storageProvider: ReportStorageProvider,
): Result<Unit>

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
package com.rubensousa.carioca.report.android.recording

import android.util.Log
import com.rubensousa.carioca.report.android.storage.ReportStorageProvider
import java.io.BufferedInputStream
import java.io.File
import java.io.FileInputStream

internal class ScreenRecorder(
private val storageProvider: com.rubensousa.carioca.report.android.storage.ReportStorageProvider,
private val storageProvider: ReportStorageProvider,
private val taskFactory: RecordingTaskFactory,
) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ package com.rubensousa.carioca.report.android.screenshot

import com.rubensousa.carioca.report.android.stage.InstrumentedStageReport
import com.rubensousa.carioca.report.android.storage.FileIdGenerator
import com.rubensousa.carioca.report.android.storage.ReportStorageProvider
import com.rubensousa.carioca.report.runtime.StageAttachment

class ScreenshotDelegate(
private val outputPath: String,
private val defaultOptions: ScreenshotOptions,
private val storageProvider: com.rubensousa.carioca.report.android.storage.ReportStorageProvider,
private val storageProvider: ReportStorageProvider,
) {

fun takeScreenshot(
Expand All @@ -32,7 +33,7 @@ class ScreenshotDelegate(
optionsOverride: ScreenshotOptions? = null,
) {
val options = optionsOverride ?: defaultOptions
val screenshotUri = com.rubensousa.carioca.report.android.screenshot.DeviceScreenshot.take(
val screenshotUri = DeviceScreenshot.take(
storageDir = storageProvider.getOutputUri(outputPath),
options = options,
filename = FileIdGenerator.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.rubensousa.carioca.report.android.stage

import com.rubensousa.carioca.report.android.storage.ReportStorageProvider
import com.rubensousa.carioca.report.runtime.StageAttachment
import com.rubensousa.carioca.report.runtime.StageReport
import java.io.OutputStream
Expand All @@ -27,7 +28,7 @@ import java.io.OutputStream
abstract class InstrumentedStageReport(
private val type: InstrumentedStageType,
protected val outputPath: String,
protected val storageProvider: com.rubensousa.carioca.report.android.storage.ReportStorageProvider,
protected val storageProvider: ReportStorageProvider,
) : StageReport() {

override fun getType(): String = type.id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ import com.rubensousa.carioca.report.android.recording.ReportRecording
import com.rubensousa.carioca.report.android.recording.ScreenRecorder
import com.rubensousa.carioca.report.android.screenshot.ScreenshotDelegate
import com.rubensousa.carioca.report.android.storage.FileIdGenerator
import com.rubensousa.carioca.report.android.storage.ReportStorageProvider
import com.rubensousa.carioca.report.runtime.ReportProperty
import com.rubensousa.carioca.report.runtime.ReportStatus
import com.rubensousa.carioca.report.runtime.StageAttachment
import com.rubensousa.carioca.report.runtime.StageStack
import com.rubensousa.carioca.report.runtime.TestMetadata
Expand All @@ -40,7 +42,7 @@ import com.rubensousa.carioca.report.runtime.TestMetadata
*/
abstract class InstrumentedTestReport internal constructor(
outputPath: String,
storageProvider: com.rubensousa.carioca.report.android.storage.ReportStorageProvider,
storageProvider: ReportStorageProvider,
val metadata: TestMetadata,
protected val interceptors: List<CariocaInstrumentedInterceptor>,
private val recordingOptions: RecordingOptions,
Expand All @@ -60,7 +62,7 @@ abstract class InstrumentedTestReport internal constructor(
screenshotDelegate: ScreenshotDelegate,
reporter: InstrumentedReporter,
interceptors: List<CariocaInstrumentedInterceptor>,
storageProvider: com.rubensousa.carioca.report.android.storage.ReportStorageProvider,
storageProvider: ReportStorageProvider,
) : this(
outputPath = outputPath,
metadata = metadata,
Expand Down Expand Up @@ -107,6 +109,15 @@ abstract class InstrumentedTestReport internal constructor(
}

fun onFailed(error: Throwable) {
/**
* We also call [onFailed] internally inside the test action reports,
* to ensure the report file is saved before the instrumentation marks the test as over.
* Since tests can just use the rule without using the stage reports,
* we can't distinguish the 2 use-cases without doing this
*/
if (getExecutionMetadata().status == ReportStatus.FAILED) {
return
}
// Take a screenshot asap to record the state on failures
screenshotDelegate.takeScreenshot(this, "Screenshot of failure")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.rubensousa.carioca.report.android.stage.InstrumentedScenario
import com.rubensousa.carioca.report.android.stage.InstrumentedStageReport
import com.rubensousa.carioca.report.android.stage.InstrumentedStageScope
import com.rubensousa.carioca.report.android.stage.InstrumentedStageType
import com.rubensousa.carioca.report.android.storage.ReportStorageProvider
import com.rubensousa.carioca.report.runtime.ExecutionIdGenerator
import com.rubensousa.carioca.report.runtime.StageStack

Expand All @@ -39,7 +40,7 @@ internal class InstrumentedBlockingDelegate(
private val stack: StageStack<InstrumentedStageReport>,
private val interceptors: List<CariocaInstrumentedInterceptor>,
private val outputPath: String,
private val storageProvider: com.rubensousa.carioca.report.android.storage.ReportStorageProvider,
private val storageProvider: ReportStorageProvider,
) : InstrumentedStageScope {

override fun screenshot(description: String, options: ScreenshotOptions?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ import com.rubensousa.carioca.report.android.stage.InstrumentedScenario
import com.rubensousa.carioca.report.android.stage.InstrumentedStageReport
import com.rubensousa.carioca.report.android.stage.InstrumentedStageScope
import com.rubensousa.carioca.report.android.stage.InstrumentedStageType
import com.rubensousa.carioca.report.android.storage.ReportStorageProvider

internal class InstrumentedBlockingStage(
type: InstrumentedStageType,
outputPath: String,
delegateFactory: InstrumentedReportDelegateFactory<InstrumentedStageScope>,
storageProvider: com.rubensousa.carioca.report.android.storage.ReportStorageProvider,
storageProvider: ReportStorageProvider,
private val id: String,
private val title: String,
) : InstrumentedStageReport(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.rubensousa.carioca.report.android.stage.InstrumentedStageScope
import com.rubensousa.carioca.report.android.stage.InstrumentedStageType
import com.rubensousa.carioca.report.android.stage.InstrumentedTestReport
import com.rubensousa.carioca.report.android.stage.InstrumentedTestScope
import com.rubensousa.carioca.report.android.storage.ReportStorageProvider
import com.rubensousa.carioca.report.runtime.ExecutionIdGenerator
import com.rubensousa.carioca.report.runtime.TestMetadata

Expand All @@ -39,7 +40,7 @@ internal class InstrumentedBlockingTest(
screenshotDelegate: ScreenshotDelegate,
reporter: InstrumentedReporter,
interceptors: List<CariocaInstrumentedInterceptor>,
storageProvider: com.rubensousa.carioca.report.android.storage.ReportStorageProvider,
storageProvider: ReportStorageProvider,
) : InstrumentedTestReport(
outputPath = outputPath,
metadata = metadata,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ import com.rubensousa.carioca.report.android.interceptor.CariocaInstrumentedInte
import com.rubensousa.carioca.report.android.recording.RecordingOptions
import com.rubensousa.carioca.report.android.screenshot.ScreenshotDelegate
import com.rubensousa.carioca.report.android.screenshot.ScreenshotOptions
import com.rubensousa.carioca.report.android.storage.ReportStorageProvider
import com.rubensousa.carioca.report.runtime.TestMetadata
import com.rubensousa.carioca.report.runtime.TestReportConfig

internal class InstrumentedBlockingTestBuilder(
private val storageProvider: com.rubensousa.carioca.report.android.storage.ReportStorageProvider,
private val storageProvider: ReportStorageProvider,
) {

fun build(
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

Libraries:

- [Android Allure Gradle Plugin](changelog_android_allure.md)
- [Test reports](changelog_reports.md)
- [JUnit4 Rules](changelog_junit4_rules.md)
- [Android Allure Gradle Plugin](changelog-android-allure)
- [Test reports](changelog-reports)
- [JUnit4 Rules](changelog-junit4-rules)
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ implementation "com.rubensousa.carioca:report-json:{{ report.version }}"
implementation "com.rubensousa.carioca:report-runtime:{{ report.version }}"
```

Jump to [this guide](android_test_reports.md) for how to integrate this library.
Jump to [this guide](test-reports-android) for how to integrate this library.


## License
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,6 @@ and can be found in `build/outputs/connected_android_test_additional_output/**/c

By default, those reports are in json format and are not really easily readable.
To visualize them properly, this library ships with an [Allure](https://allurereport.org/) plugin that can be used to generate test reports based on
the metadata collected through each test execution. Check it out in [this page](allure_plugin.md).
the metadata collected through each test execution. Check it out in [this page](android-allure-plugin).


4 changes: 2 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ plugins:

nav:
- 'Overview': index.md
- 'Android Test Reports': android_test_reports.md
- 'Android Allure Plugin': allure_plugin.md
- 'Android Test Reports': test-reports-android.md
- 'Android Allure Plugin': android-allure-plugin.md
- 'Changelog': changelog.md
- 'API': api/

0 comments on commit 900aa3f

Please sign in to comment.