-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: complete removal of TestLifecycleAware #1347
Comments
I think the whole misunderstanding comes from this block:
#2 is absolutely incorrect and we never advocate this. The methods exist so that the container's implementation can do something before/after a test, not the end user. These methods will be executed by the testing framework (e.g. see #1326 ), and this is why we need an interface - to provide a generic set of methods to be executed by the testing frameworks. |
I think you are weighing this aspect differently than the Testcontainers team. You are right that the only class making use of this feature at the moment is I'm not sure if we can come to an agreement, since we definitely put a focus on different aspects here. |
Bumps [lombok](https://github.com/rzwitserloot/lombok) from 1.16.6 to 1.18.4. <details> <summary>Changelog</summary> *Sourced from [lombok's changelog](https://github.com/rzwitserloot/lombok/blob/master/doc/changelog.markdown).* > ### v1.18.4 (October 30th, 2018) > * PLATFORM: Support for Eclipse Photon. [Issue testcontainers#1831](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1831) > * PLATFORM: Angular IDE is now recognized by the installer [Issue testcontainers#1830](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1830) > * PLATFORM: Many improvements for lombok's JDK10/11 support. > * BREAKING CHANGE: The `[**FieldNameConstants**](https://github.com/FieldNameConstants)` feature has been completely redesigned. [Issue testcontainers#1774](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1774) [FieldNameConstants documentation](https://projectlombok.org/features/experimental/FieldNameConstants) > * BREAKING CHANGE: Lombok will now always copy specific annotations around (from field to getter, from field to builder 'setter', etcetera): A specific curated list of known annotations where that is the right thing to do (generally, `[**NonNull**](https://github.com/NonNull)` style annotations from various libraries), as well as any annotations you explicitly list in the `lombok.copyableAnnotations` config key in your `lombok.config` file. Also, lombok is more consistent about copying these annotations. (Previous behaviour: Lombok used to copy any annotation whose simple name was `NonNull`, `Nullable`, or `CheckForNull`). [Issue #1570](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1570) and [Issue testcontainers#1634](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1634) > * FEATURE: Lombok's `[**NonNull**](https://github.com/NonNull)` annotation can now be used on type usages (annotation on type usages has been introduced in JDK 8). `[**Builder**](https://github.com/Builder)`'s `[**Singular**](https://github.com/Singular)` annotation now properly deals with annotations on the generics type on the collection: `[**Singular**](https://github.com/Singular) List<[**NonNull**](https://github.com/NonNull) String> names;` now does the right thing. > * FEATURE: You can now mix `[**SuperBuilder**](https://github.com/SuperBuilder)` and `toBuilder`, and `toBuilder` no longer throws `NullPointerException` if a `[**Singular**](https://github.com/Singular)`-marked collection field is `null`. [Issue #1324](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1324) > * FEATURE: delombok now supports module paths via the `--module-path` option, and will automatically add lombok itself to the module path. This should make it possible to delombok your modularized projects. [Issue testcontainers#1848](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1848) > * FEATURE: You can pass `[**args**](https://github.com/args).txt` to `delombok` to read args from the text file; useful if you have really long classpaths you need to pass to delombok. [Issue testcontainers#1795](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1795) > * BUGFIX: `[**NoArgsConstructor**](https://github.com/NoArgsConstructor)(force=true)` would try to initialize already initialized final fields in Eclipse. [Issue testcontainers#1829](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1829) > * BUGFIX: When using lombok to compile modularized (`module-info.java`-style) code, if the module name has dots in it, it wouldn't work. [Issue testcontainers#1808](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1808) > * BUGFIX: Errors about lombok not reading a module providing `org.mapstruct.ap.spi` when trying to use lombok in jigsaw-mode on JDK 11. [Issue testcontainers#1806](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1806) > * BUGFIX: Fix NetBeans compile on save. [Issue testcontainers#1770](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1770) > * BUGFIX: If you manually write your builder class so you can add a few methods of your own, and those methods refer to generated methods, you'd usually run into various bizarre error messages, but only on JDK9/10/11. This one is hard to describe, but we fixed it. [Issue testcontainers#1907](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1907) > > > ### v1.18.2 (July 26th, 2018) > * BUGFIX: mapstruct + lombok in eclipse should hopefully work again. [Issue #1359](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1359) and [mapstruct issue #1159](https://github-redirect.dependabot.com/mapstruct/mapstruct/issues/1159) > * BUGFIX: Equals and hashCode again exclude transient fields by default. [Issue testcontainers#1724](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1724) > * BUGFIX: Eclipse 'organize imports' feature (either explicitly, or if automatically triggered on saving via 'save actions') would remove the import for `lombok.var`. [Issue testcontainers#1783](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1783) > * BUGFIX: Lombok and gradle v4.9 didn't work together; that's been fixed. [Issue testcontainers#1716](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1716) and [gradle-apt-plugin issue #87](https://github-redirect.dependabot.com/tbroyer/gradle-apt-plugin/issues/87) > * FEATURE: You can now make builders for type hierarchies, using the new (experimental) `[**SuperBuilder**](https://github.com/SuperBuilder)` annotation. Thanks for the contribution, Jan Rieke. [`[**SuperBuilder**](https://github.com/SuperBuilder)` documentation](https://projectlombok.org/features/experimental/SuperBuilder) > * FEATURE: `[**NoArgsConstructor**](https://github.com/NoArgsConstructor)`, including forcing one with `lombok.config: lombok.noArgsConstructor.extraPrivate=true` now take any defaults set with `[**Builder**](https://github.com/Builder).Default` into account. [Issue #1347](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1347) > ### v1.18.0 (June 5th, 2018) > * BREAKING CHANGE: The in 1.16.22 introduced configuration key `lombok.noArgsConstructor.extraPrivate` is now `false` by default. [Issue testcontainers#1708](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1708) > * BUGFIX: Do not generate a private no-args constructor if that breaks the code. [Issue testcontainers#1703](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1703), [Issue testcontainers#1704](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1704), [Issue testcontainers#1712](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1712) > * BUGFIX: Using boolean parameters in lombok annotations would fail. [Issue testcontainers#1709](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1709) > * BUGFIX: Delombok would give an error message. [Issue testcontainers#1705](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1705) > * BUGFIX: Eclipse java10 var support didn't work if lombok was installed in your eclipse. [Issue testcontainers#1676](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1676) > * FEATURE: Google's [Flogger (a.k.a. FluentLogger)](https://google.github.io/flogger/) is now available via `[**Flogger**](https://github.com/Flogger)`. [Issue testcontainers#1697](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1697) > * FEATURE: `[**FieldNameConstants**](https://github.com/FieldNameConstants)` has been extended to support prefixes and suffixes. By default, the generated constants are prefixed with `FIELD_`. [Docs on [**FieldNameConstants**](https://github.com/FieldNameConstants)](https://projectlombok.org/features/experimental/FieldNameConstants). > > ### v1.16.22 "Envious Ferret" (May 29th, 2018) > * FEATURE: Private no-args constructor for `[**Data**](https://github.com/Data)` and `[**Value**](https://github.com/Value)` to enable deserialization frameworks (like Jackson) to operate out-of-the-box. Use `lombok.noArgsConstructor.extraPrivate = false` to disable this behavior. > * FEATURE: Methods can now be marked for inclusion in `toString`, `equals`, and `hashCode` generation. There is a new mechanism to mark which fields (and now, methods) are to be included or excluded for the generation of these methods: mark the relevant member with for example `[**ToString**](https://github.com/ToString).Include` or `[**EqualsAndHashCode**](https://github.com/EqualsAndHashCode).Exclude`. [ToString documentation](https://projectlombok.org/features/ToString) [EqualsAndHashCode documentation](https://projectlombok.org/features/EqualsAndHashCode) > * FEATURE: `[**Getter**](https://github.com/Getter)` and `[**Setter**](https://github.com/Setter)` also allow `onMethod` and `onParam` when put on a type. [Issue testcontainers#1653](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1653) > * FEATURE: `[**FieldNameConstants**](https://github.com/FieldNameConstants)` is a new feature that generates string constants for your field names. [Docs on [**FieldNameConstants**](https://github.com/FieldNameConstants)](https://projectlombok.org/features/experimental/FieldNameConstants). > * PLATFORM: Lombok can be compiled on JDK10, and should run on JDK10. [Issue testcontainers#1693](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1693) > * PLATFORM: lombok now counts as an _incremental annotation processor_ for gradle. Should speed up your gradle builds considerably! [Issue testcontainers#1580](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1580) > * PLATFORM: Fix for using lombok together with JDK9+'s new `module-info.java` feature. [Issue #985](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/985) > * BUGFIX: Solved some issues in eclipse that resulted in error 'A save participant caused problems'. [Issue #879](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/879) > * BUGFIX: Netbeans on jdk9. [Issue testcontainers#1617](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1617) > * BUGFIX: Netbeans < 9. [Issue #1555](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1555) > * PROMOTION: `var` has been promoted from experimental to the main package with no changes. The 'old' experimental one is still around but is deprecated, and is an alias for the new main package one. [var documentation](https://projectlombok.org/features/var.html). > * OLD-CRUFT: `lombok.experimental.Builder` and `lombok.experimental.Value` are deprecated remnants of when these features were still in experimental. They are now removed entirely. If your project is dependent on an older version of lombok which still has those; fret not, lombok still processes these annotations. It just no longer includes them in the jar. > > ### v1.16.20 (January 9th, 2018) > * PLATFORM: Better support for jdk9 in the new IntelliJ, Netbeans and for Gradle. > * BREAKING CHANGE: _lombok config_ key `lombok.addJavaxGeneratedAnnotation` now defaults to `false` instead of true. Oracle broke this annotation with the release of JDK9, necessitating this breaking change. ></table> ... (truncated) </details> <details> <summary>Commits</summary> - [`8451c88`](projectlombok/lombok@8451c88) pre-release version bump - [`e960f48`](projectlombok/lombok@e960f48) cleaning up the changelog in preparation for a release. - [`9b06018`](projectlombok/lombok@9b06018) [fixes testcontainers#1907] This one is hard to describe; due to builder being a bit overze... - [`f5b1069`](projectlombok/lombok@f5b1069) add jdk11 to docker builds - [`0336537`](projectlombok/lombok@0336537) fixing the tests added in the previous commits by janrieke to match alternati... - [`d8de0e3`](projectlombok/lombok@d8de0e3) Merge branch 'wildcardsSingularFix' of git://github.com/janrieke/lombok into ... - [`eca219e`](projectlombok/lombok@eca219e) eliminate ‘you are using private API’ warnings by streamlining all reflective... - [`182cb0c`](projectlombok/lombok@182cb0c) [java-11] up dependency on lombok.patcher, including asm7 - [`c02263a`](projectlombok/lombok@c02263a) Merge pull request [testcontainers#1923](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1923) from abargnesi/fix-maven-issue-management - [`4cf36b2`](projectlombok/lombok@4cf36b2) Merge pull request [testcontainers#1917](https://github-redirect.dependabot.com/rzwitserloot/lombok/issues/1917) from kkocel/master - Additional commits viewable in [compare view](projectlombok/lombok@v1.16.6...v1.18.4) </details> <br /> [![Dependabot compatibility score](https://api.dependabot.com/badges/compatibility_score?dependency-name=org.projectlombok:lombok&package-manager=maven&previous-version=1.16.6&new-version=1.18.4)](https://dependabot.com/compatibility-score.html?dependency-name=org.projectlombok:lombok&package-manager=maven&previous-version=1.16.6&new-version=1.18.4) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- **Note:** This repo was added to Dependabot recently, so you'll receive a maximum of 5 PRs for your first few update runs. Once an update run creates fewer than 5 PRs we'll remove that limit. You can always request more updates by clicking `Bump now` in your [Dependabot dashboard](https://app.dependabot.com). <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot badge me` will comment on this PR with code to add a "Dependabot enabled" badge to your readme Additionally, you can set the following in the `.dependabot/config.yml` file in this repo: - Update frequency (including time of day and day of week) - Automerge options (never/patch/minor, and dev/runtime dependencies) - Pull request limits (per update run and/or open at any time) - Out-of-range updates (receive only lockfile updates, if desired) - Security updates (receive only security updates, if desired) Finally, you can contact us by mentioning @dependabot. </details>
Even if there is no explicit recommendation about it, the existence of 2 different places for logic before/after test could confuse newcomers:
Why containers should contains this logic inside? It's not a container logic, it's a test logic. A test logic should be placed inside tests, or inside some test helpers. A developer should be able to have full control under his tests. No need to impose some test behavior to the developer.
If containers will just provide methods with the same logic as we have now in the
Yes, it's not a big deal to add this integration. But it worth mentioning.
I don't think that this is important. Number of integrations with the
I'm not sure about it. As I already mentioned,
That's great. Just provide this functionality as a methods without assumptions about caller use cases. Let's take database snapshots for example. To give this functionality you can add a method like
That's why I created this proposal. I believe that even if we have different views or use cases we can still come to the right decision. I think you are concentrating too much on a current situation and historical reasons. Of course, testcontainers has features to do some stuff before/after tests for a while. This features is familiar and feels usable. But just imagine that testcontainers doen't have any kind of this functionality. And all other features are in the library. Would you add something like That's the main reason why I propose to delete |
I think you're speculating. Newcomers will never know about that interface. We have it, so that the testing frameworks can integrate with Testcontainers. If a newcomer writes an integration, he is considered an advanced user.
Because they serve different purposes. You, as a user of your test framework, use the hooks to do your stuff. Your test framework, if integrated with Testcontainers, uses
Never, as a user. As mentioned already, you use them only then you integrate with a testing framework.
Then you don't use the rules /
Take a look at the project's name. It will give you a hint ;)
We are. Testcontainers is the result of many years of development, community communication and feedback listening. We would not become the most popular Docker testing library out there without it. Just think about it.
One of the most beloved aspect of Testcontainers is that you create a container, annotate it with
I suggest you to think about it differently. We have our view on the problem because we were solving a problem. Meanwhile, you're trying to push your idea, with your only argument is "it doesn't provide any unique functionality". If you really want to help the project, interview a few QA people about their experience with the browser container and how it "magically works without them doing anything because they are not hardcore developers".
That's a speculation. "Less code" is never an advantage per se, as long as we're (as a team) ready to maintain it. Also, when you say "us" - what does it mean to you? |
I fully agree with @bsideup and @kiview here. A lot of what Testcontainers is for is to stop developers having to write/extend boilerplate classes. If we were being strict about giving full control to developers and having no test framework/lifecycle coupling, we wouldn't have The trouble with opinionated design decisions is that they tend to have disadvantages, and tend to face disagreement at some time. I think that this is the case here, but unfortunately I don't see a way to find a middle ground. I'm sorry, but we might have to 'agree to disagree'. FWIW, If/when we get around to creating a non-testing container library, with Testcontainers becoming a testing-related library on top of it, this interface is likely to move and/or change. I'm afraid that now is a bit too soon to know exactly what we'll do with it though. BTW I do really appreciate that you've put a lot of time and thought into this proposal, and been civil throughout on a topic you feel strongly about. Thank you for this. |
I'm talking about developers who saw
I'm not sure about what expectations you are talking about. Could you give an example?
Maybe I was not 100% clear, but I never proposed this. I'm talking about logic inside these methods. This logic should be available for the developers without
You are talking about the usage part. But I was talking about the implementation of containers. In which situation should I put the logic after test in the container, and in which in the test-framework hook? This is the confusing part in my opinion.
But in that case, I will lose start/stop functionality too, which is always useful.
About which problem you are talking about?
Well, yes, I don't have enough side look about this. But for me, there is no difference between doing something inside the test or after the test. If QA people can call methods on the container inside the test body, they can do the same after the test, using the test-framework feature.
This is a bit philosophical, but I do not agree with your opinion. Less code is always better than any code. You could have bugs in this code. You should evolve this code. But it's not really important. When I'm talking about "few advantages" I, first of all, mean less opinionated core.
It's contextual. I will try to be more clear.
I think integration with test frameworks could use only start/stop. And it's enough for most cases.
As far as I know, at the current moment, only So, your position is that testcontainers provides docker containers which are useful mostly for tests. And also, testcontainers provides some default behavior inside the tests with the methods from |
@LMnet I respect the time and the thought you put into this discussion, but TBH, this whole argument seems like the ultimate example in bikeshedding and I therefore won't go on participating in it any further. We all have limited capacities for supporting and developing the project and this is not the hill I plan to die on. It's all about prioritization and pragmatism in the face of limited resources and if you look at the open issues and feature requests, I'd assume you agree, there are more valuable things to spend energy on. Not mentioning the hassle for our users when pushing a breaking change. Are there any concrete problems you are facing in your developer life because of |
I want to give some prehistory. I'm working on a new Scala API in the testcontainers-scala. Current Scala API uses Without But if you ignore deprecated stuff and see on the current state of a testcontainers-java you could see, that the only obstacle on the way of the generic core module is That's why I created this proposal. I didn't mention testcontainers-scala a lot because it's an internal course of a testcontainers-scala and this course should not affect testcontainers-java. I tried to use arguments specific only for the java library. I can accept and understand that testcontainers-java is not ready now for this separation to 2+n modules. But as I already said, we now only one step away from the generic core. If testcontainers-java will continue its opinionated course, it potentially means more test-specific functionality (like more containers with methods from the |
I don't think you should be doing it in testcontainers-scala. That library is just a wrapper (or a Scala language binding) around the main one. We do plan to create "containercore" library), but it will take time and it is quite pointless to achieve it in a separate library given the main project is still heavily test-oriented (not just the lifecycle, but also the cleanup at JVM exit, for example, or random names).
Sorry, but you're missing the bigger picture. Please leave it to the Testcontainers team to decide. |
It's absolutely true and I could miss some parts.
This is not a final decision atm. But it looks like Scala API could progress a lot faster because it's a lot smaller. That's why I think I could achieve this in the next few releases.
Well, from the messages in this discussion it looks like this is pretty long plans. But if this is a current long-term strategy, I want to help these plans come true earlier. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe this is a mistake, please reply to this comment to keep it open. If there isn't one already, a PR to fix or at least reproduce the problem in a test case will always help us get back on track to tackle this. |
This issue has been automatically closed due to inactivity. We apologise if this is still an active problem for you, and would ask you to re-open the issue if this is the case. |
This proposal based on a recent slack discussion: https://testcontainers.slack.com/archives/C9EJ7TVT7/p1553315996086400.
I propose to delete from the core project
TestLifecycleAware
class.Current state
As far as I understand, current project direction looks like this:
I fully support this course and I believe that it will simplify the code base and make it more maintainable. This will allow the library to grow faster in the future. In addition, I'm a user and contributor to the testcontainers-scala library, which relies on a testcontainers-java. For the scala facade, the simple and test-framework agnostic core will be a huge win. It will lead to a simpler integration and will give the possibility to delete some non-elegant code from the testcontainers-scala.
One of the steps in this direction was deprecation of a
starting
,succeeded
,failed
andfinished
methods. These methods describe container lifecycle in the tests. They are declared in theFailureDetectingExternalResource
class. This is aTestRule
for the JUnit 4. All containers are based on this class. When library user wants to add some logic before or after tests, he could use one of those methods.Disadvantage of the
FailureDetectingExternalResource
was in hard coupling with JUnit 4. This test rule will work only with this test framework.As a replacement for the
FailureDetectingExternalResource
were introducedStartable
andTestLifecycleAware
interfaces. InStartable
there is 2 methods:start
andstop
, for start and stop logic of a container. InTestLifecycleAware
there isbeforeTest
andafterTest
, for the test lifecycle logic.This new approach is better because it's test-framework agnostic. All test-framework specific logic will be in the integration layer, and this layer will use methods from the
Startable
andTestLifecycleAware
interfaces.But, I think,
Startable
is enough, and we don't need to haveTestLifecycleAware
in the core.Motivation
To describe why we can remove
TestLifecycleAware
and don't lose any functionality, I would like to make a digression.Let's think about typical developer experience with the test frameworks. For examples I will use JUnit 4.
If I want to create a test with JUnit 4, I will create a class with methods, place my test logic in these methods, and mark them with
@Test
annotation. Like this:But it would work only for the simplest cases. Sometimes I need to do something before or after each test. For this JUnit 4 gives me a possibility to mark methods in the test class with the
@Before
and@After
annotations. A code inside these methods will be called before/after each test. For example:But sometimes I need to do something before or after all tests in the test class. For this case, JUnit 4 gives me
@BeforeClass
and@AfterClass
annotations. For example:But sometimes it's not enough to do some unconditional code after the test. Sometimes I need to do something only for failed tests, or only for succeeded. For this case, JUnit 4 gives me
TestWatcher
rule. For example:We could find similar functionality in other test frameworks too. In JUnit 5 we have
@Before/AfterEach
,@Before/AfterAll
andTestWatcher
. In TestNG we have a lot of before/after annotations, including@Before/AfterMethod
and@Before/AfterClass
. In scalatest, which I use with the testcontainers-scala, I also have similar functionality. And I believe, that almost all test frameworks have some sort of this. Developers are familiar with the patterns from their test framework. These patterns are described in the documentation. They could be googled easily.Now, let's imagine, that developer decided to use testcontainers for some reason. And, for example, he needs to do something after each test, and he uses JUnit 4. A familiar pattern for the developer is using framework functionality. So, he would use
@After
annotation for this:As you could see in the example, the developer could place any logic in the
after
method. He also could somehow interact with the container: call some methods, get some info from it.With this example, I want to show that containers are not something special from the test framework view and from the developer view. It's just a java object with some methods, which developer could use in the different places in the test class. As I said before, this is a familiar pattern for the developer.
Now, let's return to the
TestLifecycleAware
. It's supposed that methods from theTestLifecycleAware
will be called by the test framework, not a developer. And I think this is the main breaking moment of aTestLifecycleAware
.So, with all other objects (fixtures, counters, instances to test, etc) developer should interact in one way, but with the containers in some other way. Idiomatic logic for testcontainers, in that case, would look like this:
@Before/@After
annotation.For example:
It means that instead of using familiar and unconditional pattern, which is recommended by the test framework, testcontainers force developers to add an exception to these patterns in case of containers.
Of course, I could just not use
TestLifecycleAware
at all, and use familiar patterns from my test framework. But what If I want to use the container with already implemented methods from theTestLifecycleAware
? This container will impose this behavior. And In the case when I want another behavior I will have to create my own container through inheritance and override this behavior.Disadvantages of the
TestLifecycleAware
Let's sum up all disadvantages:
TestLifecycleAware
impose me behavior from these methods. If I don't need it, I have to override it.TestLifecycleAware
methods. So,TestLifecycleAware
is useful only for some scenarios.TestLifecycleAware
on multiple containers. For some scenarios, it could be important.TestLifecycleAware
itself doesn't solve any problem. All problems already solved on a test-framework side.TestLifecycleAware
just adds some extra level of abstraction.Alternative approach
I propose to just not use
TestLifecycleAware
at all. Instead, just use functionality and patterns from your test framework. They already have all the things we need. We don't need to reimplement this in the testcontainers.Also, without
TestLifecycleAware
we could deleteTestDescription
. It needs only for theTestLifecycleAware
.Advantages of the alternative approach
TestLifecycleAware
is not big or complex part of a project, but any deletion from the core is always a good thing for the library.TestLifecycleAware
developers from the testcontainers team should think about the integration ofTestLifecycleAware
with the test framework. It's some extra code, a bit of extra complexity. For example, I'm now working on a new API for a testcontainers-scala. And integration with theTestLifecycleAware
takes ~20 lines of code. It's not too much, but all integration is ~100 lines of code. So,TestLifecycleAware
is 1/5 of my current integration code. I think it's a noticeable number.TestLifecycleAware
(excluding deprecated code) somehow tie core with the testing case. WithoutTestLifecycleAware
core module will not have any assumption of a use case. The core will provide containers in the form of java objects. These containers will have some fields and methods. A developer could interact with these containers in a way he wants — containers not assume anything about the use case. It means less coupling with the test scenario, more wide use case for the core. Of course, you could use testcontainers in that way today too. But the existence ofTestLifecycleAware
in that case looks like a redundant, leaky abstraction.Disdvantages of the alternative approach
I can see these disadvantages:
TestLifecycleAware
methods, and we removed these methods, developers will have to reimplement this logic on their side. This problem may be relevant to theBrowserWebDriverContainer
. This is the only container in the library with this logic. Possible solution: improveBrowserWebDriverContainer
to give a simple way to reimplement this logic on the user side. Ideally, with the single method call. Another solution, which could be used with the previous one, is to provide functionality from theBrowserWebDriverContainerю.afterTest
on the integration level.Summary
I believe that we just don't need
TestLifecycleAware
. And if we deleteTestLifecycleAware
we don't lose anything, and only get some advantages I described above.The text was updated successfully, but these errors were encountered: