{"id":17280815,"url":"https://github.com/lefou/mill-integrationtest","last_synced_at":"2025-03-22T18:34:34.473Z","repository":{"id":40465855,"uuid":"171845774","full_name":"lefou/mill-integrationtest","owner":"lefou","description":"Integration testing for mill plugins","archived":false,"fork":false,"pushed_at":"2025-01-22T10:27:02.000Z","size":262,"stargazers_count":13,"open_issues_count":10,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-18T14:05:24.568Z","etag":null,"topics":["build-tool","integration-testing","mill","mill-plugin","scala"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lefou.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"lefou"}},"created_at":"2019-02-21T09:54:24.000Z","updated_at":"2025-01-22T10:27:06.000Z","dependencies_parsed_at":"2023-02-14T12:16:56.244Z","dependency_job_id":"f5b6cf45-682d-4fee-9e3e-d4b4b1bee6ae","html_url":"https://github.com/lefou/mill-integrationtest","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lefou%2Fmill-integrationtest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lefou%2Fmill-integrationtest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lefou%2Fmill-integrationtest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lefou%2Fmill-integrationtest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lefou","download_url":"https://codeload.github.com/lefou/mill-integrationtest/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245003688,"owners_count":20545646,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["build-tool","integration-testing","mill","mill-plugin","scala"],"created_at":"2024-10-15T09:22:04.004Z","updated_at":"2025-03-22T18:34:34.179Z","avatar_url":"https://github.com/lefou.png","language":"Scala","readme":"= mill-integrationtest - Integration test plugin for mill plugins\n:version: 0.7.1\n:mill-platform: 0.11\n:scala-platform: 2.13\n:min-mill-version: 0.9.3\n:example-mill-version: 0.11.0\n:project-home: https://github.com/lefou/mill-integrationtest\n:scoverage-version: 1.4.11\n:munit-version: 0.7.7\n:toc:\n:toc-placement: preamble\n\nifdef::env-github[]\nimage:https://github.com/lefou/mill-integrationtest/workflows/.github/workflows/build.yml/badge.svg[Build Status (GitHub Actions), link=\"https://github.com/lefou/mill-integrationtest/actions\"]\nimage:https://codecov.io/gh/lefou/mill-integrationtest/branch/main/graph/badge.svg[Test Coverage (Codecov.io), link=\"https://codecov.io/gh/lefou/mill-integrationtest\"]\nimage:https://javadoc.io/badge2/de.tototec/de.tobiasroeser.mill.integrationtest_mill{mill-platform}_{scala-platform}/scaladoc.svg[\"ScalaDoc\", link = \"https://javadoc.io/doc/de.tototec/de.tobiasroeser.mill.integrationtest_mill{mill-platform}_{scala-platform}\"]\nendif::[]\n\nIntegration testing for https://github.com/com-lihaoyi/mill[Mill] plugins.\n\n== Quickstart\n\nHere we assume, you use mill {example-mill-version} and develop a mill plugin named `demo`\n\n[source,scala]\n----\n// build.sc\nimport mill._, mill.scalalib._\nobject demo extends ScalaModule with PublishModule {\n  // ...\n}\n----\n\nFirst you need to add a new test module, e.g. `itest`.\n\n[source,scala,subs=\"verbatim,attributes\"]\n----\n// build.sc\nimport $ivy.`de.tototec::de.tobiasroeser.mill.integrationtest::{version}`\nimport de.tobiasroeser.mill.integrationtest._\n\nobject demo extends ScalaModule with PublishModule {\n  // ...\n}\n\nobject itest extends MillIntegrationTestModule {\n\n  def millTestVersion = \"{example-mill-version}\"\n\n  def pluginsUnderTest = Seq(demo)\n\n}\n----\n\nYour test cases will be located in the source directory of the newly added `itest` project.\nThe idea is that each sub-directory represents a separate mill project representing a test case.\n\nYour project should now look similar to this:\n\n----\n.\n+-- demo/\n|   +-- src/\n|\n+-- itest/\n    +-- src/\n        +-- 01-first-test/\n        |   +-- build.sc\n        |   +-- src/\n        |\n        +-- 02-second-test/\n            +-- build.sc\n----\n\nAs the buildfiles `build.sc` in your test cases typically want to access the locally built plugin(s),\nthe plugins publishes all modules referenced under `pluginsUnderTest` and `temporaryIvyModule` to a temporary ivy repository,\njust before the test is executed.\nThe mill version used in the integration test then uses that temporary ivy repository.\n\nBecause you are using your locally developed plugin,\ninstead of referring to your plugin with `import $ivy.'your::plugin:version'`,\nyou should use the following line, which ensures that you use the correct locally build plugins.\n\n[source,scala]\n----\n// build.sc\nimport $file.plugins\n----\n\nEffectively, at execution time, Mill is also loading file `plugins.sc`,\na file which was generated just before the test started to execute.\nIt will `$ivy` import all dependencies you listed in `pluginsUnderTest`.\n(If you want to find out how this works, read https://ammonite.io/#import$file[this])\n\n.Example for a generated `plugins.sc`\n[source,scala]\n----\n// Import a locally published version of the plugin under test\nimport $ivy.`org.example:mill-demo_2.12:0.1.0-SNAPSHOT`\n----\n\n== Configuration and Targets\n\nMill {min-mill-version} or newer is required. See also \u003c\u003cVersion Compatibility Matrix\u003e\u003e.\n\nThe `MillIntegrationTestModule` trait provides the following targets:\n\n.Mandatory configuration\n* `def millTestVersion: T[String]`\n  The mill version used for executing the test cases.\n  Used by `downloadMillTestVersion` to automatically download.\n\n* `def pluginsUnderTest: Seq[PublishModule]` -\n  The plugins used in the integration test.\n  You should at least add your plugin under test here.\n  You can also add additional libraries, e.g. those that assist you in the test result validation (e.g. a local test support project).\n  The defined modules will be published into a temporary ivy repository before the tests are executed.\n  In your test `build.sc` file, instead of the typical `import $ivy.` line,\n  you should use `import $file.plugins` to include all plugins that are defined here.\n\n.Optional configuration\n* `def temporaryIvyModules: Seq[PublishModule]` -\n  Additional modules you need in the temporary ivy repository, but not in the resulting mill build classpath.\n  The defined modules will be published into a temporary ivy repository before the tests are executed.\n  This is almost the same as `pluginsUnderTest`, but does not end up in the generated `plugins.sc`.\n\n* `def sources: Sources` -\n  Locations where integration tests are located.\n  Each integration test is a sub-directory, containing a complete test mill project.\n\n* `perTestResources: Sources` -\n  Shared test resources, will be copied as-is into each test case working directory before the test is run.\n  You can also generate these, making some test setups easier (e.g. including additional classpath resources).\n\n* `def testCases: Target[Seq[PathRef]]` -\n  The directories each representing a mill test case.\n  Derived from `sources`.\n\n* `def testInvocations: Target[Seq[(PathRef, Seq[TestInvocation.Targets])]]` -\n  The test invocations to test the project.\n  Defaults to run `TestInvokation.Targets` with the targets from [[testTargets]] and expecting successful execution.\n  For each test case, you can define a seq of invocations.\n\n* `def testTargets: Target[Seq[String]]` -\n  _Deprecated: Please use `testInvocations` instead_\n  The targets which are called to test the project.\n  Defaults to `verify`, which should implement test result validation.\n\n* `def downloadMillTestVersion: T[PathRef]` -\n  Download the mill version as defined by `millTestVersion`.\n  Override this, if you need to use a custom built mill version.\n  Returns the `PathRef` to the mill executable (must have the executable flag).\n\n* `def useCachedMillDownload: T[Boolean]` -\n  If `true`, the downloaded mill version used for tests will be cached to the system cache dir (e.g. `~/.cache`).\n  Default: `true`.\n\n* `def showFailedRuns: T[Boolean]` -\n   If `true`, The run log of a failed test case will be shown.\n   Default: `true`.\n\n* `def prefetchIvyDeps: T[Agg[Dep]]` -\n  Add dependencies here, which you want to prefetch into your local coursier cache before acually running the tests.\n  Each dependency is resolved and fetched independently, so it is possible to fetch multiple versions of the same artifact.\n  Use this target to prepare integration test which should run offline.\n\n.Commands / Action Targets\n* `def test(args: String*): Command[Seq[TestCase]]` -\n  Run the integration tests. The args here are the actual test cases that will\n  run. By default this will run them all, but it's also possible to just pass\n  the single test name in to run that single test.\n\n* `def testCached: Target[Seq[TestCase]]` -\n  Run the integration tests (same as `test`), but only if any input has changed since the last run.\n\n* `def prepareOffline: Command[Unit]` -\n  Prepares going offline by pre-fetching all known dependencies.\n\n== How can I ...\n\n=== Run multiple targets in one go\n\nUse `testInvocations` to configure the targets to execute.\n[source,scala]\n----\ndef testInvocations = T{\n  Seq(\n    pathRefToTest1 -\u003e Seq(\n      TestInvocation.Targets(Seq(\"target1\", \"target2\"))\n    )\n  )\n}\n----\n\n=== Run multiple mill invocations with different or even the same targets\n\nUse `testInvocations` to configure the targets to execute.\n[source,scala]\n----\ndef testInvocations = T{\n  Seq(\n    PathRef()-\u003e Seq(\n      // first mill run\n      TestInvocation.Targets(Seq(\"target1\", \"target2\")),\n      // second mill run\n      TestInvocation.Targets(Seq(\"target3\", \"target4\")),\n      // third mill run with same targets\n      TestInvocation.Targets(Seq(\"target3\", \"target4\"))\n    )\n  )\n}\n----\n\n=== Run a single defined integration test\n\nGiven a setup like this:\n\n[source,scala]\n----\ndef testInvocations = T{\n  Seq(\n    PathRef(testBaseDir / \"exampleTestDir\") -\u003e Seq(\n      TestInvocation.Targets(Seq(\"target1\")),\n    )\n  )\n}\n----\n\nYou can run an individual target by passing in the name to `itest`:\n\n[source]\n---\nmill itest exampleTestDir\n---\n\n=== Test failing mill targets\n\nUse `testInvocations` to configure the targets to execute and fail.\n[source,scala]\n----\ndef testInvocations = T{\n  Seq(\n    pathRefToTest1 -\u003e Seq(\n      // first 2 targets that should succeed\n      TestInvocation.Targets(Seq(\"target1\", \"target2\")),\n      // third target should fail with exit code 1\n      TestInvocation.Targets(Seq(\"target3\"), expectedExitCode = 1)\n    )\n  )\n}\n----\n\n=== Better prints context of failed targets\n\nMany test libraries provide nice asserting APIs which produce helpful error messages.\n\nFor example, use `munit`'s Assertions when defining your test targets\n\n[source,scala,subs=\"attributes\"]\n----\n// itest/src/project1/build.sc\nimport $ivy.`org.scalameta::munit:{munit-version}`, munit.Assertions._\ndef verify() = T.command {\n  assert(None.isDefined)\n  val fixedScala = read(os.pwd / \"foo\" / \"src\" / \"Fix.scala\")\n  val expected   = \"\"\"object Fix {\n                   |  def procedure(): Unit = {} xxx\n                   |}\n                   |\"\"\".stripMargin\n  assertEquals(fixedScala, expected)\n}\n----\n\n=== Properly test a mill plugin that uses a worker implementation\n\nYou probably want to load the worker in a separated classloader,\nhence it should not end up in mills classpath.\nDefine the plugin module with `pluginsUnderTest` and the worker module with `temporaryIvyModules`.\nThis will ensure that all modules will be build and published to the test ivy repository,\nbut only those listed in `pluginsUnderTest` will end up in the generated `plugins.sc`.\n\n[source,scala]\n----\ndef itest extends MillIntegrationTestModule {\n  def pluginsUnderTest = Seq(plugin)\n  def temporaryIvyModules = Seq(api, worker)\n  // ...\n}\n----\n\n=== Test with multiple mill versions, e.g. on a CI server\n\n\nMill hasn't a stable API (yet) and there are no binary compatibility guarantees.\nSo, it is a good idea to add all supported mill version to your CI setup.\n\nThe recommended way of supporting multiple mill versions is via mill's built-in support for cross building (`mill.define.Cross`).\n\n[source,scala]\n----\nval millItestVersions = Seq(\"0.7.3\", \"0.7.2\", \"0.7.1\", \"0.7.0\")\n\nobject itest extends Cross[ItestCross](millItestVersions: _*)\nclass ItestCross(millItestVersion: String) extends MillIntegrationTestModule {\n  def millTestVersion = millItestVersion\n  // correct the source path (remove the extra level for the mill version)\n  override def millSourcePath = super.millSourcePath / os.up\n  ..\n}\n----\n\nNow you can run a single integration test with\n\n[source,sh]\nmill itest[0.7.3].test\n\nOr you can all integration test in parallel with\n\n[source,sh]\nmill -j 0 itest[_].test\n\n=== Cross-Testing a cross built mill-plugin\n\nIn case you cross build your mill plugin to support multiple API versions,\nyou need to parametrize your plugins under test.\n\n[source,scala]\n----\ntrait Deps {\n  def millVersion = \"0.7.0\"\n  def scalaVersion = \"2.13.2\"\n\n  val millMain = ivy\"com.lihaoyi::mill-main:${millVersion}\"\n  val millScalalib = ivy\"com.lihaoyi::mill-scalalib:${millVersion}\"\n}\nobject Deps_0_7 extends Deps\nobject Deps_0_6 extends Deps {\n  override def millVersion = \"0.6.0\"\n  override def scalaVersion = \"2.12.10\"\n}\n\n// The Mill API versions you want to support\nval millApiVersions: Map[String, Deps] = ListMap(\n  \"0.7\" -\u003e Deps_0_7,\n  \"0.6\" -\u003e Deps_0_6\n)\n\n// The Released Mill versions you want to use in your integration tests\nval millItestVersions = Seq(\n  \"0.7.3\", \"0.7.2\", \"0.7.1\", \"0.7.0\",\n  \"0.6.3\", \"0.6.2\", \"0.6.1\", \"0.6.0\"\n)\n\n// Your mill plugin\nobject core extends Cross[CoreCross](millApiVersions.keysIterator.toSeq: _*)\nclass CoreCross(val millApiVersion: String) extends CrossScalaModule with PublishModule {\n  def deps: Deps = millApiVersions(millApiVersion)\n  override def crossScalaVersion = deps.scalaVersion\n  override def compileIvyDeps = Seq(\n    deps.millMain,\n    deps.millScalalib\n  )\n  ..\n}\n\n// Your integration test for your mill plugin\nobject itest extends Cross[ItestCross](millItestVersions: _*)\nclass ItestCross(millItestVersion: String)  extends MillIntegrationTestModule {\n  val millApiVersion = millItestVersion.split(\"[.]\").take(2).mkString(\".\")\n  override def millSourcePath: Path = super.millSourcePath / os.up\n  override def millTestVersion = millItestVersion\n  override def pluginsUnderTest = Seq(core(millApiVersion))\n  ..\n}\n----\n\nHave a look at the `build.sc` of this mill plugin to see how this is done.\nHere are also link to two other mill plugins that uses this technique (at the time of writing this):\n\n* https://github.com/lefou/mill-vcs-version\n* https://github.com/lefou/mill-kotlin\n\n=== Collecting integration test coverage data with Scoverage\n\nMill already provides the `mill.contrib.scoverage.ScoverageModule` as part of its contrib plugin collection.\nTo ensure you're using the scoverage-enhanced class files (which are configured to write coverage data into a directrory)\nin your integration tests, you need to make sure to use the right JAR with the enhanced class files `\u003cmodule\u003e.scoverage.jar` instead of the `\u003cmodule\u003e.jar`.\n\nTo accomplish this, you need to override the protected `pluginsUnderTestDetails` target and swap the binary JAR with it's `ScoverageModule` version.\nThis trick has the effect that we install the scoverage-enhanced JAR file into the test ivy repository.\n\nIf you also use `temporaryIvyModules`, you need to do the same for `temporaryIvyModulesDetails`.\n\n[IMPORTANT]\n--\nIt's important to only use the scoverage-enhanced classes in tests! Do not distribute them.\n\nIf you would use them outside of your test case, loading them or executing their code would fail in almost all cases.\n--\n\n[source,scala,subs=\"attributes\"]\n----\nclass core extends ScalaModule with PublishModule with ScoverageModule {\n  override def scoverageVersion = \"{scoverage-version}\"\n  ..\n}\n\nobject itest extends MillIntegrationTestModule {\n  override def pluginsUnderTest = Seq(core)\n  override def pluginUnderTestDetails: Task.Sequence[(PathRef, (PathRef, (PathRef, (PathRef, (PathRef, Artifact)))))] =\n    T.traverse(pluginsUnderTest) { p =\u003e\n      val jar = p match {\n        case p: ScoverageModule =\u003e p.scoverage.jar\n        case p =\u003e p.jar\n      }\n      jar zip (p.sourceJar zip (p.docJar zip (p.pom zip (p.ivy zip p.artifactMetadata))))\n    }\n  ..\n}\n----\n\nAlso, you need to make sure, that you load the required  scoverage runtime library into your mill under test.\nYou can do this by adding the following `$ivy` import to your `build.sc` in each test case.\n\n[source,scala,subs=\"attributes\"]\nimport $ivy.`org.scoverage::scalac-scoverage-runtime:{scoverage-version}`\n\nNow, when you run the integration tests coverage data will be gathered and can be used to generate reports.\n\n[source,sh]\nmill -j 0 itest.test\nmill core.scoverage.htmlReport\n\n== How is `mill-integrationtest` tesing itself?\n\nGlad you asked!\n\n`mill-integrationtest` is using a previously released version of itself to test itself.\nThis means we have three levels of `mill-integrationtest`:\n\n1. The project itself, configured in `build.sc`\n2. A previously released version of `mill-integrationtest` to run the integration tests, configured in the cross module `itest` (in top-level `build.sc`).\nThe cross parameter denotes the Mill version to run the tests against.\n3. And finally the freshly built `mill-integrationtest` plugin under test, used in the test cases located under `itest/src`.\n\nThis makes understanding the test setup and the build/test output rather hard to read, even for me.\n\n== Download\n\nYou can download binary releases from\nhttps://search.maven.org/artifact/de.tototec/de.tobiasroeser.mill.integrationtest_mill{mill-platform}_{scala-platform}[Maven Central].\n\nNewer versions of this plugin (after version 0.3.3) have a _mill platform suffix_ in the artifact name.\nIf you use Mill 0.9.10 or above, you can use the double colon (`::`) between artifact name and version to always use the right Mill binary platform.\nOn older Mill versions, you need to add the platform suffix manually.\n\n.Mill Platform suffix\n[options=\"header\"]\n|===\n\n| mill version | mill platform | suffix | example\n| 0.10.x | 0.10 | `_mill0.10` | ```import $ivy.`de.tototec::de.tobiasroeser.mill.integrationtest::{version}````\n| 0.9.3 - 0.9.x | 0.9 | `_mill0.9` | ```import $ivy.`de.tototec::de.tobiasroeser.mill.integrationtest_mill0.9:{version}````\n|===\n\n\n== License\n\nThis project is published under the https://www.apache.org/licenses/LICENSE-2.0[Apache License, Version 2.0].\n\n\n== Version Compatibility Matrix\n\nMill is still in active development, and has no stable API yet.\nHence, not all mill-integrationtest versions work with every mill version.\n\nThe following table shows a matrix of compatible mill and mill-integrationtest versions.\nNewer version of mill may or may not work. (Feel free to update this page via a pull request, thanks.)\n\n.Version Compatibility Matrix\n[options=\"header\"]\n|===\n| mill-integrationtest | mill\n| 0.7.0 | 0.9.x, 0.10.x, 0.11.0-M8\n| 0.6.1 | 0.9.3 - 0.9.x, 0.10.x\n| 0.6.0 | 0.9.3 - 0.9.x, 0.10.x\n| 0.5.1 | 0.9.3 - 0.9.x, 0.10.x\n| 0.5.0  | 0.9.3 - 0.9.12, 0.10.0 - 0.10.1\n| 0.4.2  | 0.9.3 - 0.9.12, 0.10.0 - 0.10.1\n| 0.4.1 | 0.6.2 - 0.9.12\n| 0.4.0 | 0.6.2 - 0.9.6, (not 0.9.7), 0.9.8 - 0.9.9\n| 0.3.3 | 0.6.2 - 0.8.0\n| 0.3.2 | 0.6.2 - 0.8.0\n| 0.3.1 | 0.6.2 - 0.8.0\n| 0.3.0 | 0.6.2 - 0.8.0\n| 0.2.1 | 0.6.0 - 0.6.3\n| 0.2.0 | 0.5.7\n| 0.1.2 | 0.5.7\n| 0.1.1 | 0.5.7\n| 0.1.0 | 0.3.6 - 0.5.3\n|===\n\n== About\n\nmill::\nhttps://github.com/lihaoyi/mill[Mill] is a Scala-based open source build tool.\nIn my opinion the best build tool for the JVM.\nIt is fast, reliable and easy to understand.\n\nme::\n+\n--\nhttps://github.com/lefou/[I'm] a professional software developer and love to write and use open source software.\nI'm actively developing and maintaining mill as well as https://github.com/lefou?utf8=%E2%9C%93\u0026tab=repositories\u0026q=topic%3Amill\u0026type=\u0026language=[several mill plugins].\n\nIf you like my work, please star it on GitHub. You can also support me via https://github.com/sponsors/lefou[GitHub Sponsors].\n--\n\nContributing::\nIf you found a bug or have a feature request, please open a {project-home}/issues[new issue on GitHub].\nI also accept {project-home}/pulls[pull requests on GitHub].\n\n\n== Changelog\n\n=== 0.7.1 - 2023-06-07\n\n* Support for Mill 0.11 API\n* Update Scala to 2.13.11\n\n=== 0.7.0 - 2023-04-27\n\n* Support for Mill 0.11.0-M8\n* Slight API changes to accommodate to Mill 0.11 (only return values of `pluginUnderTestDetails` and `temoraryIvyModuleDetails`)\n* Minor documentation and internal improvements\n\n=== 0.6.1 - 2022-07-11\n\n* Fixed default value for `TestInvocation.Targets.noServer`\n\n=== 0.6.0 - 2022-04-13\n\n* Support running Mill under test in server mode\n* mill-integrationtest is now also CI tested on Windows\n\n=== 0.5.1 - 2022-04-12\n\n* Fixed non-functional tests under Windows\n\n=== 0.5.0 - 2022-03-09\n\n* Support to specify environment variables for test runs\n* Support `moduleDeps` of tests plugins (to publish them transitively into the test repository)\n* Updated toolchain to use Mill 0.10.1 and newer plugins\n\n=== 0.4.2 - 2022-03-08\n\n* Added support for Mill 0.10\n* Added support for mill milestone versions\n* Added `prefetcIvyDeps` and offline support\n* Dependency updates\n* Dropped support for older Mill versions\n\n=== 0.4.1 - 2021-06-09\n\n* Improved output, esp. in error case\n* Added new `perTestResources` target\n* Work around binary compatibility issues with mill 0.9.7\n\n=== 0.4.0 - 2020-11-30\n\n* Added support for mill 0.9.3 while maintaining backward-compatible versions down to mill 0.6.2\n* Introduce a new artifact name suffix (`_mill0.9` for mil 0.9.3) to support multiple mill API versions.\n* Various version bumps: scalatest 3.2.3, scalafmt 2.7.5, scoverage 1.4.2\n\n=== 0.3.3 - 2020-07-03\n\n* New option `showFailedRuns` to always show output of failed runs\n\n=== 0.3.2 - 2020-07-03\n\n* Re-use mill download cache under `~/.cache`\n* Added integration tests\n* Improved output and error reporting\n* Integration test runs now will be written to a dedicated log file\n* When mill it run in debug mode (`-d`), the complete log of a failed run will be printed after the test summary\n* More documentation\n\n\n=== 0.3.1 - 2020-05-19\n\n* Fixed issues on Windows when setting script permissions\n\n=== 0.3.0 - 2020-05-15\n\n* Cross-publishing for Mill API 0.6.2 (Scala 2.12) and mill API 0.7.0 (Scala 2.13)\n* Use newer mill 0.6.2 API to publish to custom ivy repositories\n* Fixes Windows support\n* Only scan existing source dirs for test cases\n\n=== 0.2.1 - 2020-02-27\n\n* Bumped Mill API to 0.6.0\n\n=== 0.2.0 - 2020-02-27\n\n* Added support to run selective tests\n* Targets `test` and `testCached` no return the test result\n* new target `testCachedArgs` to control args feeded to testCachedArgs\n* Test executor now generated a mill script which allows you to manually invoke mill in\n  a test destination directory\n* New target `testInvocations` providing much finer control over executed targets and their\n  expected exit value\n\n=== 0.1.2 - 2020-02-18\n\n* New target `temporaryIvyModulesDetails`\n* New target `testCached`\n\n=== 0.1.1 - 2020-01-08\n\n* Version bump mill API to 0.5.7\n\n=== 0.1.0 - 2019-02-21\n\n* Initial public release\n","funding_links":["https://github.com/sponsors/lefou"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flefou%2Fmill-integrationtest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flefou%2Fmill-integrationtest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flefou%2Fmill-integrationtest/lists"}