Skip to content

[Feature request] Add test artifacts to XML. #19

Description

@TDuffinNTU

Hello! I'm not sure if this project is still developed actively, but I thought to suggest this for yourself or someone else if they were up for it.

Note I have only ever used Azure Devops Pipelines for test automation and CI/CD on flutter projects. The terminology may not match what others use!

Feature description

In CI/CD runners such as Azure Devops, there is ad hoc support for "attachments" which may be added to test results. While this isn't within the Junit spec, and may not be standard across automation platforms, it would be a useful feature to allow test results to publish supporting artifacts such as Golden "diff images" and log files that may not be surfaced by the test runner automatically.

In essence, they are simply relative paths to existing files at the time of the test execution, and it would be up to the automation platform to handle finding and publishing of the artifacts. The XML attachments simply couple this artifact to the test that produced it.

Benefits

Platforms such as ADO display test results within a "test run", which allow developers to see which tests are failing, how often, and assign bug tickets to them among other things. When an attachment is detected, it is uploaded during a "Publish test results" job on the pipeline, producing a result like so:

As mentioned before, you could use this to automate golden test reporting to levels not possible without the feature. Currently, unless I'm mistaken, devs usually upload the files within "test/**/goldens/failures/*.png" after a test run, usually requiring some detection to ensure the pipeline doesn't try publishing on a successful run (which throws an error on ADO, not sure for others) and have to manually thumb through potentially dozens of files to download/view and then reupload if they wanted to use the test results UI to, say, make a bug report.

Implementation

I'm not too sure how this could be achieved necessarily, it may be one for upstream dartlang devs to tackle as they could add it to the JSON reporter in a trivial manner (making your work much easier!)... but

In most cases a test runner will log the path of any artifacts it produces. Or you may be able to infer it from the logs of a particular test:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: one widget whose rasterized image matches golden image "goldens/ci/login_page_light.png"
  Actual: <Instance of 'Future<Image>'>
   Which: does not match

When the exception was thrown, this was the stack:
#0      fail (package:matcher/src/expect/expect.dart:187:31)
#1      _expect.<anonymous closure> (package:matcher/src/expect/expect.dart:155:13)
<asynchronous suspension>
<asynchronous suspension>
#8      expectLater.<anonymous closure> (package:flutter_test/src/widget_tester.dart:508:19)
<asynchronous suspension>
#9      FlutterGoldenTestAdapter.withForceUpdateGoldenFiles (package:alchemist/src/golden_test_adapter.dart:198:14)
<asynchronous suspension>
#10     FlutterGoldenTestRunner.run (package:alchemist/src/golden_test_runner.dart:137:9)
<asynchronous suspension>
#11     goldenTest.<anonymous closure> (package:alchemist/src/golden_test.dart:177:7)
<asynchronous suspension>
#12     testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:192:15)
<asynchronous suspension>
#13     TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:1952:5)
<asynchronous suspension>
<asynchronous suspension>
(elided 7 frames from dart:async and package:stack_trace)

The test description was:
  renders correctly on light theme (variant: CI)
════════════════════════════════════════════════════════════════════════════════════════════════════

In this case, the file goldens/ci/login_page_light.png suggests that goldens/ci/failures/* would contain the artifacts. Of course, relatively to the path of the test itself which the test reporter will have logged by this point.

This feels very specific to just one example of a test output, though, so perhaps there would be work needed within the dart team to surface artifacts within the JSON to be consumed later.

Alternatively, you could do the inverse and, given a file test/login_page/goldens/ci/failures/login_page_light.png, you could read the file hierarchy to infer that the nearest test file (or some other condition) is the "owner". It would be up to the user to supply the location of files they wish to attach. You could even provide subcommands to add arbitrary files to a particular test result, regardless of file hierarchy.

Conclusion

Let me know what you think, or if this is perhaps something out of scope for the project. I wonder what others would think of this as a standalone tool 🤔

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions