You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@calcite.apache.org by Julian Hyde <jh...@apache.org> on 2021/11/16 22:26:52 UTC

[DISCUSS] Refactoring tests

I am working on https://issues.apache.org/jira/browse/CALCITE-4885,
"Fluent test fixtures so that dependent projects can write parser,
validator and rules tests".

I wanted to give you all a heads up, because it's going to change
quite a few lines of code.

Here's the problem I'm trying to solve. Calcite defines APIs such as
RelRule, SqlOperator, and we encourage people to implement them in
their projects (not necessarily contribute them back). But experience
has shown that if you want to write, say, a planner rule, you'd better
write some tests for it. And to write tests, you need to sub-class
RelOptRulesTest.

So, 4885 is about making it easier to write those kinds of tests.

But - spoiler alert - subclassing the test classes isn't the way to
go. Your subclass will inherit all of the tests from the base class.
If you keep mutable state ("fixtures") in your test class, then
maintaining that state gets messy as more tests add more state. We
have added abstractions such as "tester" [1] but it's still pretty
complicated.

I am refactoring the test along the following lines:

Test classes (e.g. RelOptRulesTest) contain tests but have no state.
They have a "fixture()" method that returns a fixture. Often there is
also a "sql(String sql)" method that just does
"fixture().withSql(sql)".

A fixture class (renamed from the helper classes called "Sql" in
various tests) has a lot of methods that allow you to test things. But
the only state in the fixture is a tester and a config. That state is
immutable; each time you set a property, you create a new fixture that
wraps a new copy of the config.

A test config class is immutable and has lots of data fields.

If the test uses reference files, the config will contain a
DiffRepository. Subclasses can use a different DiffRepository (mapping
to a different .xml file) but still use the same fixture
implementation.

A tester implements the nuts and bolts (e.g. parsing SQL, converting
SQL to RelNode, planning). It has no state; the methods accept lots of
parameters, such as whether decorrelation is enabled, from the config.
There's usually only one implementation of tester, but you can
override for special reasons (e.g. an implementation of the parser
tester that converts the AST back to SQL and tries to parse it a
second time).

With these changes, people will be able to create a test that
instantiates a fixture, calls some methods to configure it, and then
calls some methods to run their test. See FixtureTest and Fixtures
[2]. They can do that in any class, not necessarily a subclass of an
existing Calcite test.

Our test framework is not covered by semantic versioning. People in
dependent projects who depend on our test framework may have to fix up
their tests when they upgrade. It shouldn't be too bad.

In the bug Vladimir suggested that we take this opportunity to move
from Hamcrest matchers to AssertJ. I disagree. I'm not convinced that
AssertJ is so much better that moving to it is worth the disruption.
And in any case, this change is about figuring out the lifecycle (e.g.
how do I configure my test to add and remove rules from the planner,
when the planner doesn't exist until I'm half way through my test) and
I don't think AssertJ helps with that.

I am going to make fixtures, configs and testers top-level classes
(i.e. not inner classes). It makes them easier to extend.

I might make fixtures into interfaces whose methods all have defaults.
Then people can easily subclass fixtures; they could even inherit from
multiple fixtures.

Let me know if you have ideas or concerns. I recommend that people who
have written tricky tests (e.g. TopDownOptTest) track this
development.

Julian

[1] https://github.com/apache/calcite/blob/4b1e9ed1a513eae0c873a660b755bb4f27b39da9/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java#L568

[2] https://github.com/julianhyde/calcite/commit/0286f78b0db0e364f3225f004b32853de2685a39

Re: [DISCUSS] Refactoring tests

Posted by Julian Hyde <jh...@gmail.com>.
I haven’t heard from anyone.

I plan to merge https://issues.apache.org/jira/browse/CALCITE-4986 <https://issues.apache.org/jira/browse/CALCITE-4986> "Make HepProgram thread-safe” in the next hour or two, then I will squash/rebase/merge https://issues.apache.org/jira/browse/CALCITE-4885 <https://issues.apache.org/jira/browse/CALCITE-4885> "Fluent test fixtures” tomorrow.

They’re both significant changes, review welcome.

Julian



> On Jan 12, 2022, at 10:11 AM, Julian Hyde <jh...@gmail.com> wrote:
> 
> After a month or so of work I have a PR for review. See https://github.com/apache/calcite/pull/2685/ <https://github.com/apache/calcite/pull/2685/>.
> 
> The PR is huge (80 commits, 127 files changed, 20k lines added/removed) so may be hard to digest. I recommend that you read the commit log to understand the various refactorings. Note that SqlOperatorBaseTest both moved (from main to testkit) and changed name (to SqlOperatorTest) so diffing it might require some ingenuity.
> 
> At this point I am especially interested in high-level comments (Does the test/fixture/tester/factory split work? Are there any other candidates for this refactoring?). If you have a lot of low-level comments (e.g. spelling mistakes) just send me a PR.
> 
> It’s probably several days before I will squash, rebase and consider merging to main.
> 
> Julian
>  
> 
>> On Nov 22, 2021, at 4:12 AM, Stamatis Zampetakis <zabetak@gmail.com <ma...@gmail.com>> wrote:
>> 
>> Hello,
>> 
>> I generally agree with the problems and goals set by CALCITE-4885 so
>> definitely worth pushing this forward.
>> 
>> I also like the ideas for being compatible with JUnit5 extensions etc., but
>> I guess it could be something to address later one and does not need to be
>> part of CALCITE-4885.
>> If and when somebody comes with a concrete proposal we can evaluate this.
>> 
>> Same reasoning goes for AssertJ; it may be beneficial for the project but
>> let's evaluate it separately.
>> 
>> If I understand well, both AssertJ and extensions via JUnit5 may come in
>> conflict with the new APIs exposed by CALCITE-4885 so it would be nice if
>> we can advance all these in the same release.
>> 
>> Last I wanted to mention that although people consuming Calcite releases
>> may not care much about big changes in the testing code, those who maintain
>> forks of the main repo will have a few more challenges to address when they
>> cherry-pick changes.
>> This is not an argument to push back the feature but just an additional
>> element for completing the picture.
>> 
>> Best,
>> Stamatis
>> 
>> On Wed, Nov 17, 2021 at 7:15 AM Vladimir Sitnikov <
>> sitnikov.vladimir@gmail.com <ma...@gmail.com>> wrote:
>> 
>>> Jacques>This sounds like it will mean we will need to make calcite-core
>>> test artifacts available
>>> 
>>> Test artifacts publication is yet another anti-pattern just like "base test
>>> class".
>>> This change has been discussed:
>>> https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1 <https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1>
>>> 
>>> If you want to depend on a class from tests, consider moving it to /testkit
>>> module:
>>> 
>>> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
>>> 
>>> Jacques>We should think about the rules around Kotlin
>>> 
>>> What happens in calcite-core/tests stays in calcite-core/tests :)
>>> 
>>> It is reasonable to assume that testkit module would have dependencies,
>>> and testkit would provide API that is usable from Java and other JVM
>>> languages.
>>> 
>>> In that regard, Kotlin dependency in testkit is not much different from
>>> Quidem or commons-lang3.
>>> Consumers might use Quidem if it fits just like they could use Kotlin if it
>>> fits.
>>> 
>>> Vladimir
>>> 
> 


Re: [DISCUSS] Refactoring tests

Posted by Julian Hyde <jh...@gmail.com>.
After a month or so of work I have a PR for review. See https://github.com/apache/calcite/pull/2685/ <https://github.com/apache/calcite/pull/2685/>.

The PR is huge (80 commits, 127 files changed, 20k lines added/removed) so may be hard to digest. I recommend that you read the commit log to understand the various refactorings. Note that SqlOperatorBaseTest both moved (from main to testkit) and changed name (to SqlOperatorTest) so diffing it might require some ingenuity.

At this point I am especially interested in high-level comments (Does the test/fixture/tester/factory split work? Are there any other candidates for this refactoring?). If you have a lot of low-level comments (e.g. spelling mistakes) just send me a PR.

It’s probably several days before I will squash, rebase and consider merging to main.

Julian
 

> On Nov 22, 2021, at 4:12 AM, Stamatis Zampetakis <za...@gmail.com> wrote:
> 
> Hello,
> 
> I generally agree with the problems and goals set by CALCITE-4885 so
> definitely worth pushing this forward.
> 
> I also like the ideas for being compatible with JUnit5 extensions etc., but
> I guess it could be something to address later one and does not need to be
> part of CALCITE-4885.
> If and when somebody comes with a concrete proposal we can evaluate this.
> 
> Same reasoning goes for AssertJ; it may be beneficial for the project but
> let's evaluate it separately.
> 
> If I understand well, both AssertJ and extensions via JUnit5 may come in
> conflict with the new APIs exposed by CALCITE-4885 so it would be nice if
> we can advance all these in the same release.
> 
> Last I wanted to mention that although people consuming Calcite releases
> may not care much about big changes in the testing code, those who maintain
> forks of the main repo will have a few more challenges to address when they
> cherry-pick changes.
> This is not an argument to push back the feature but just an additional
> element for completing the picture.
> 
> Best,
> Stamatis
> 
> On Wed, Nov 17, 2021 at 7:15 AM Vladimir Sitnikov <
> sitnikov.vladimir@gmail.com> wrote:
> 
>> Jacques>This sounds like it will mean we will need to make calcite-core
>> test artifacts available
>> 
>> Test artifacts publication is yet another anti-pattern just like "base test
>> class".
>> This change has been discussed:
>> https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1
>> 
>> If you want to depend on a class from tests, consider moving it to /testkit
>> module:
>> 
>> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
>> 
>> Jacques>We should think about the rules around Kotlin
>> 
>> What happens in calcite-core/tests stays in calcite-core/tests :)
>> 
>> It is reasonable to assume that testkit module would have dependencies,
>> and testkit would provide API that is usable from Java and other JVM
>> languages.
>> 
>> In that regard, Kotlin dependency in testkit is not much different from
>> Quidem or commons-lang3.
>> Consumers might use Quidem if it fits just like they could use Kotlin if it
>> fits.
>> 
>> Vladimir
>> 


Re: [DISCUSS] Refactoring tests

Posted by Stamatis Zampetakis <za...@gmail.com>.
Hello,

I generally agree with the problems and goals set by CALCITE-4885 so
definitely worth pushing this forward.

I also like the ideas for being compatible with JUnit5 extensions etc., but
I guess it could be something to address later one and does not need to be
part of CALCITE-4885.
If and when somebody comes with a concrete proposal we can evaluate this.

Same reasoning goes for AssertJ; it may be beneficial for the project but
let's evaluate it separately.

If I understand well, both AssertJ and extensions via JUnit5 may come in
conflict with the new APIs exposed by CALCITE-4885 so it would be nice if
we can advance all these in the same release.

Last I wanted to mention that although people consuming Calcite releases
may not care much about big changes in the testing code, those who maintain
forks of the main repo will have a few more challenges to address when they
cherry-pick changes.
This is not an argument to push back the feature but just an additional
element for completing the picture.

Best,
Stamatis

On Wed, Nov 17, 2021 at 7:15 AM Vladimir Sitnikov <
sitnikov.vladimir@gmail.com> wrote:

> Jacques>This sounds like it will mean we will need to make calcite-core
> test artifacts available
>
> Test artifacts publication is yet another anti-pattern just like "base test
> class".
> This change has been discussed:
> https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1
>
> If you want to depend on a class from tests, consider moving it to /testkit
> module:
>
> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
>
> Jacques>We should think about the rules around Kotlin
>
> What happens in calcite-core/tests stays in calcite-core/tests :)
>
> It is reasonable to assume that testkit module would have dependencies,
> and testkit would provide API that is usable from Java and other JVM
> languages.
>
> In that regard, Kotlin dependency in testkit is not much different from
> Quidem or commons-lang3.
> Consumers might use Quidem if it fits just like they could use Kotlin if it
> fits.
>
> Vladimir
>

Re: [DISCUSS] Refactoring tests

Posted by Julian Hyde <jh...@gmail.com>.
I think sub-classing and parameterizing tests are both valid approaches. I agree that during review of 4952, parameterizing looked like the best option. But you had to add metadataConfig as a a parameter to lots of methods, which caused a massive conflict with my changes, and paving over your changes was the right approach.

Parameterized tests are probably best when the all parameter values are “similar". But they wouldn’t work well if, say, the parameter is a particular parser implementation and one parser implementation lives in a project that Calcite cannot even see.

My ’test fixture’ approach works well for that scenario because in the dependent project you would sub-class the test to provide a modified fixture (with, say, a different parser and perhaps some other changes to configuration) and then the tests would all run on that fixture.

A compromise approach might be for each test method to accept a fixture as the one and only argument. Then you could change other aspects of the fixture without having to refactor every test method.

I did ensure that the same tests were being run before and after rebase. The biggest concern was whether the MetadataConfig is being set correctly in the tests. I had to create MetadataConfig.NOP and use it in 3 tests because otherwise the cluster’s metadata was being overwritten mid-way through the test. Different overloads of MetadataConfig.applyMetadata were called at different points within the test, and they would conflict. The NOP was a way to neutralize the conflicting calls. I’m not proud of that workaround, but I believe the necessary tests get run.

Julian


> On Jan 25, 2022, at 3:34 PM, Jacques Nadeau <ja...@apache.org> wrote:
> 
>> 
>> In your fix for https://issues.apache.org/jira/browse/CALCITE-4952 <
>> https://issues.apache.org/jira/browse/CALCITE-4952> you made
>> RelMetadataTest a parameterized test, so that each case could be called
>> with two metadata providers. I undid that, and made it into a test with a
>> protected fixture() method, so that a sub-class can run the same tests with
>> a different provider. I believe that the test coverage is the same, albeit
>> via different means.
> 
> 
> Hmm. I actually started with the subclass pattern but after feedback during
> review, Stamatis and I agreed that subclassing was an anti-pattern and thus
> I went through the "fun" process of refactoring to use parameterization.
> 
> In terms of confirming that the change to RelMetadataTest didn't disrupt
> coverage, any chance you ran a diff on test output pre/post to confirm that
> at least all the same test cases are running? (That's a really hard giant
> file diff to compare given all the refactoring.)
> 
> 
> 
> On Sat, Jan 22, 2022 at 9:41 PM Julian Hyde <jh...@gmail.com> wrote:
> 
>> Gavin, Thanks for the kind words.
>> 
>> All, I have now squashed and rebased onto latest master. The squashed
>> commit is
>> https://github.com/julianhyde/calcite/commit/cb59231a72e23be260b21670012af33c47c2610e.
>> I plan to merge to master on Monday.
>> 
>> Jacques, You may wish to carefully review my changes to RelMetadataTest.
>> In your fix for https://issues.apache.org/jira/browse/CALCITE-4952 <
>> https://issues.apache.org/jira/browse/CALCITE-4952> you made
>> RelMetadataTest a parameterized test, so that each case could be called
>> with two metadata providers. I undid that, and made it into a test with a
>> protected fixture() method, so that a sub-class can run the same tests with
>> a different provider. I believe that the test coverage is the same, albeit
>> via different means.
>> 
>> Julian
>> 
>> 
>>> On Jan 22, 2022, at 9:53 AM, Gavin Ray <ra...@gmail.com> wrote:
>>> 
>>> Thank you for doing this, after reading the overview these changes seem
>>> like they will make a number of things easier related to testing.
>>> Super useful too when you're trying to start building something with
>>> Calcite but don't know it well enough to figure out how to put all the
>>> pieces together yourself.
>>> 
>>> On Fri, Jan 21, 2022 at 3:57 PM Julian Hyde <jh...@gmail.com>
>> wrote:
>>> 
>>>> If it helps you review, I have created a ’summary’ document with a
>>>> description of the changes. It will become the commit message when I
>>>> squash, rebase, and merge to master.
>>>> 
>>>> 
>>>> 
>> https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md
>>>> <
>>>> 
>> https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md
>>> 
>>>> 
>>>> 
>>>> Julian
>>>> 
>>>> 
>>>>> On Jan 19, 2022, at 9:08 PM, Jacques Nadeau <ja...@apache.org>
>> wrote:
>>>>> 
>>>>> Unfortunately, the last minute attendance of the meetup today threw my
>>>>> schedule off and I won't be able to look at this for at least a few
>> days.
>>>>> Don't feel obligated to hold up for me.
>>>>> 
>>>>> On Wed, Jan 19, 2022, 9:04 AM Jacques Nadeau <ja...@apache.org>
>> wrote:
>>>>> 
>>>>>> FYI, I'm trying to do a thorough review today (as much as possible
>> with
>>>>>> patch this size).
>>>>>> 
>>>>>> On Wed, Jan 19, 2022, 4:36 AM Michael Mior <mm...@apache.org> wrote:
>>>>>> 
>>>>>>> Thanks for doing this Julian! I haven't been able to do a detailed
>>>> review,
>>>>>>> but from my skim of the PR, this looks like a nice improvement. I
>> think
>>>>>>> it's always been a bit difficult for new Calcite developers to write
>>>> good
>>>>>>> tests, especially for new modules. So anything that helps that
>>>> experience
>>>>>>> is very welcome.
>>>>>>> 
>>>>>>> --
>>>>>>> Michael Mior
>>>>>>> mmior@apache.org
>>>>>>> 
>>>>>>> 
>>>>>>> Le mer. 17 nov. 2021 à 01:15, Vladimir Sitnikov <
>>>>>>> sitnikov.vladimir@gmail.com>
>>>>>>> a écrit :
>>>>>>> 
>>>>>>>> Jacques>This sounds like it will mean we will need to make
>>>> calcite-core
>>>>>>>> test artifacts available
>>>>>>>> 
>>>>>>>> Test artifacts publication is yet another anti-pattern just like
>> "base
>>>>>>> test
>>>>>>>> class".
>>>>>>>> This change has been discussed:
>>>>>>>> https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1
>>>>>>>> 
>>>>>>>> If you want to depend on a class from tests, consider moving it to
>>>>>>> /testkit
>>>>>>>> module:
>>>>>>>> 
>>>>>>>> 
>>>>>>> 
>>>> 
>> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
>>>>>>>> 
>>>>>>>> Jacques>We should think about the rules around Kotlin
>>>>>>>> 
>>>>>>>> What happens in calcite-core/tests stays in calcite-core/tests :)
>>>>>>>> 
>>>>>>>> It is reasonable to assume that testkit module would have
>>>> dependencies,
>>>>>>>> and testkit would provide API that is usable from Java and other JVM
>>>>>>>> languages.
>>>>>>>> 
>>>>>>>> In that regard, Kotlin dependency in testkit is not much different
>>>> from
>>>>>>>> Quidem or commons-lang3.
>>>>>>>> Consumers might use Quidem if it fits just like they could use
>> Kotlin
>>>>>>> if it
>>>>>>>> fits.
>>>>>>>> 
>>>>>>>> Vladimir
>>>>>>>> 
>>>>>>> 
>>>>>> 
>>>> 
>>>> 
>> 
>> 


Re: [DISCUSS] Refactoring tests

Posted by Jacques Nadeau <ja...@apache.org>.
>
> In your fix for https://issues.apache.org/jira/browse/CALCITE-4952 <
> https://issues.apache.org/jira/browse/CALCITE-4952> you made
> RelMetadataTest a parameterized test, so that each case could be called
> with two metadata providers. I undid that, and made it into a test with a
> protected fixture() method, so that a sub-class can run the same tests with
> a different provider. I believe that the test coverage is the same, albeit
> via different means.


Hmm. I actually started with the subclass pattern but after feedback during
review, Stamatis and I agreed that subclassing was an anti-pattern and thus
I went through the "fun" process of refactoring to use parameterization.

In terms of confirming that the change to RelMetadataTest didn't disrupt
coverage, any chance you ran a diff on test output pre/post to confirm that
at least all the same test cases are running? (That's a really hard giant
file diff to compare given all the refactoring.)



On Sat, Jan 22, 2022 at 9:41 PM Julian Hyde <jh...@gmail.com> wrote:

> Gavin, Thanks for the kind words.
>
> All, I have now squashed and rebased onto latest master. The squashed
> commit is
> https://github.com/julianhyde/calcite/commit/cb59231a72e23be260b21670012af33c47c2610e.
> I plan to merge to master on Monday.
>
> Jacques, You may wish to carefully review my changes to RelMetadataTest.
> In your fix for https://issues.apache.org/jira/browse/CALCITE-4952 <
> https://issues.apache.org/jira/browse/CALCITE-4952> you made
> RelMetadataTest a parameterized test, so that each case could be called
> with two metadata providers. I undid that, and made it into a test with a
> protected fixture() method, so that a sub-class can run the same tests with
> a different provider. I believe that the test coverage is the same, albeit
> via different means.
>
> Julian
>
>
> > On Jan 22, 2022, at 9:53 AM, Gavin Ray <ra...@gmail.com> wrote:
> >
> > Thank you for doing this, after reading the overview these changes seem
> > like they will make a number of things easier related to testing.
> > Super useful too when you're trying to start building something with
> > Calcite but don't know it well enough to figure out how to put all the
> > pieces together yourself.
> >
> > On Fri, Jan 21, 2022 at 3:57 PM Julian Hyde <jh...@gmail.com>
> wrote:
> >
> >> If it helps you review, I have created a ’summary’ document with a
> >> description of the changes. It will become the commit message when I
> >> squash, rebase, and merge to master.
> >>
> >>
> >>
> https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md
> >> <
> >>
> https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md
> >
> >>
> >>
> >> Julian
> >>
> >>
> >>> On Jan 19, 2022, at 9:08 PM, Jacques Nadeau <ja...@apache.org>
> wrote:
> >>>
> >>> Unfortunately, the last minute attendance of the meetup today threw my
> >>> schedule off and I won't be able to look at this for at least a few
> days.
> >>> Don't feel obligated to hold up for me.
> >>>
> >>> On Wed, Jan 19, 2022, 9:04 AM Jacques Nadeau <ja...@apache.org>
> wrote:
> >>>
> >>>> FYI, I'm trying to do a thorough review today (as much as possible
> with
> >>>> patch this size).
> >>>>
> >>>> On Wed, Jan 19, 2022, 4:36 AM Michael Mior <mm...@apache.org> wrote:
> >>>>
> >>>>> Thanks for doing this Julian! I haven't been able to do a detailed
> >> review,
> >>>>> but from my skim of the PR, this looks like a nice improvement. I
> think
> >>>>> it's always been a bit difficult for new Calcite developers to write
> >> good
> >>>>> tests, especially for new modules. So anything that helps that
> >> experience
> >>>>> is very welcome.
> >>>>>
> >>>>> --
> >>>>> Michael Mior
> >>>>> mmior@apache.org
> >>>>>
> >>>>>
> >>>>> Le mer. 17 nov. 2021 à 01:15, Vladimir Sitnikov <
> >>>>> sitnikov.vladimir@gmail.com>
> >>>>> a écrit :
> >>>>>
> >>>>>> Jacques>This sounds like it will mean we will need to make
> >> calcite-core
> >>>>>> test artifacts available
> >>>>>>
> >>>>>> Test artifacts publication is yet another anti-pattern just like
> "base
> >>>>> test
> >>>>>> class".
> >>>>>> This change has been discussed:
> >>>>>> https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1
> >>>>>>
> >>>>>> If you want to depend on a class from tests, consider moving it to
> >>>>> /testkit
> >>>>>> module:
> >>>>>>
> >>>>>>
> >>>>>
> >>
> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
> >>>>>>
> >>>>>> Jacques>We should think about the rules around Kotlin
> >>>>>>
> >>>>>> What happens in calcite-core/tests stays in calcite-core/tests :)
> >>>>>>
> >>>>>> It is reasonable to assume that testkit module would have
> >> dependencies,
> >>>>>> and testkit would provide API that is usable from Java and other JVM
> >>>>>> languages.
> >>>>>>
> >>>>>> In that regard, Kotlin dependency in testkit is not much different
> >> from
> >>>>>> Quidem or commons-lang3.
> >>>>>> Consumers might use Quidem if it fits just like they could use
> Kotlin
> >>>>> if it
> >>>>>> fits.
> >>>>>>
> >>>>>> Vladimir
> >>>>>>
> >>>>>
> >>>>
> >>
> >>
>
>

Re: [DISCUSS] Refactoring tests

Posted by Julian Hyde <jh...@gmail.com>.
I have merged my PR, and marked https://issues.apache.org/jira/browse/CALCITE-4885 <https://issues.apache.org/jira/browse/CALCITE-4885> fixed.

If my changes make it difficult to rebase, I apologize. If you need explanation for the changes I made, check the (very detailed) commit message, browse the un-squashed commits in https://github.com/julianhyde/calcite/tree/4885-test-fixtures.0 <https://github.com/julianhyde/calcite/tree/4885-test-fixtures.0>, or ask for my help on this thread.

Julian


> On Jan 22, 2022, at 9:41 PM, Julian Hyde <jh...@gmail.com> wrote:
> 
> Gavin, Thanks for the kind words.
> 
> All, I have now squashed and rebased onto latest master. The squashed commit is https://github.com/julianhyde/calcite/commit/cb59231a72e23be260b21670012af33c47c2610e <https://github.com/julianhyde/calcite/commit/cb59231a72e23be260b21670012af33c47c2610e>. I plan to merge to master on Monday.
> 
> Jacques, You may wish to carefully review my changes to RelMetadataTest. In your fix for https://issues.apache.org/jira/browse/CALCITE-4952 <https://issues.apache.org/jira/browse/CALCITE-4952> you made RelMetadataTest a parameterized test, so that each case could be called with two metadata providers. I undid that, and made it into a test with a protected fixture() method, so that a sub-class can run the same tests with a different provider. I believe that the test coverage is the same, albeit via different means.
> 
> Julian
> 
> 
>> On Jan 22, 2022, at 9:53 AM, Gavin Ray <ray.gavin97@gmail.com <ma...@gmail.com>> wrote:
>> 
>> Thank you for doing this, after reading the overview these changes seem
>> like they will make a number of things easier related to testing.
>> Super useful too when you're trying to start building something with
>> Calcite but don't know it well enough to figure out how to put all the
>> pieces together yourself.
>> 
>> On Fri, Jan 21, 2022 at 3:57 PM Julian Hyde <jhyde.apache@gmail.com <ma...@gmail.com>> wrote:
>> 
>>> If it helps you review, I have created a ’summary’ document with a
>>> description of the changes. It will become the commit message when I
>>> squash, rebase, and merge to master.
>>> 
>>> 
>>> https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md <https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md>
>>> <
>>> https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md>
>>> 
>>> 
>>> Julian
>>> 
>>> 
>>>> On Jan 19, 2022, at 9:08 PM, Jacques Nadeau <ja...@apache.org> wrote:
>>>> 
>>>> Unfortunately, the last minute attendance of the meetup today threw my
>>>> schedule off and I won't be able to look at this for at least a few days.
>>>> Don't feel obligated to hold up for me.
>>>> 
>>>> On Wed, Jan 19, 2022, 9:04 AM Jacques Nadeau <ja...@apache.org> wrote:
>>>> 
>>>>> FYI, I'm trying to do a thorough review today (as much as possible with
>>>>> patch this size).
>>>>> 
>>>>> On Wed, Jan 19, 2022, 4:36 AM Michael Mior <mm...@apache.org> wrote:
>>>>> 
>>>>>> Thanks for doing this Julian! I haven't been able to do a detailed
>>> review,
>>>>>> but from my skim of the PR, this looks like a nice improvement. I think
>>>>>> it's always been a bit difficult for new Calcite developers to write
>>> good
>>>>>> tests, especially for new modules. So anything that helps that
>>> experience
>>>>>> is very welcome.
>>>>>> 
>>>>>> --
>>>>>> Michael Mior
>>>>>> mmior@apache.org
>>>>>> 
>>>>>> 
>>>>>> Le mer. 17 nov. 2021 à 01:15, Vladimir Sitnikov <
>>>>>> sitnikov.vladimir@gmail.com>
>>>>>> a écrit :
>>>>>> 
>>>>>>> Jacques>This sounds like it will mean we will need to make
>>> calcite-core
>>>>>>> test artifacts available
>>>>>>> 
>>>>>>> Test artifacts publication is yet another anti-pattern just like "base
>>>>>> test
>>>>>>> class".
>>>>>>> This change has been discussed:
>>>>>>> https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1
>>>>>>> 
>>>>>>> If you want to depend on a class from tests, consider moving it to
>>>>>> /testkit
>>>>>>> module:
>>>>>>> 
>>>>>>> 
>>>>>> 
>>> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
>>>>>>> 
>>>>>>> Jacques>We should think about the rules around Kotlin
>>>>>>> 
>>>>>>> What happens in calcite-core/tests stays in calcite-core/tests :)
>>>>>>> 
>>>>>>> It is reasonable to assume that testkit module would have
>>> dependencies,
>>>>>>> and testkit would provide API that is usable from Java and other JVM
>>>>>>> languages.
>>>>>>> 
>>>>>>> In that regard, Kotlin dependency in testkit is not much different
>>> from
>>>>>>> Quidem or commons-lang3.
>>>>>>> Consumers might use Quidem if it fits just like they could use Kotlin
>>>>>> if it
>>>>>>> fits.
>>>>>>> 
>>>>>>> Vladimir
>>>>>>> 
>>>>>> 
>>>>> 
>>> 
>>> 
> 


Re: [DISCUSS] Refactoring tests

Posted by Julian Hyde <jh...@gmail.com>.
Gavin, Thanks for the kind words.

All, I have now squashed and rebased onto latest master. The squashed commit is https://github.com/julianhyde/calcite/commit/cb59231a72e23be260b21670012af33c47c2610e. I plan to merge to master on Monday.

Jacques, You may wish to carefully review my changes to RelMetadataTest. In your fix for https://issues.apache.org/jira/browse/CALCITE-4952 <https://issues.apache.org/jira/browse/CALCITE-4952> you made RelMetadataTest a parameterized test, so that each case could be called with two metadata providers. I undid that, and made it into a test with a protected fixture() method, so that a sub-class can run the same tests with a different provider. I believe that the test coverage is the same, albeit via different means.

Julian


> On Jan 22, 2022, at 9:53 AM, Gavin Ray <ra...@gmail.com> wrote:
> 
> Thank you for doing this, after reading the overview these changes seem
> like they will make a number of things easier related to testing.
> Super useful too when you're trying to start building something with
> Calcite but don't know it well enough to figure out how to put all the
> pieces together yourself.
> 
> On Fri, Jan 21, 2022 at 3:57 PM Julian Hyde <jh...@gmail.com> wrote:
> 
>> If it helps you review, I have created a ’summary’ document with a
>> description of the changes. It will become the commit message when I
>> squash, rebase, and merge to master.
>> 
>> 
>> https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md
>> <
>> https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md>
>> 
>> 
>> Julian
>> 
>> 
>>> On Jan 19, 2022, at 9:08 PM, Jacques Nadeau <ja...@apache.org> wrote:
>>> 
>>> Unfortunately, the last minute attendance of the meetup today threw my
>>> schedule off and I won't be able to look at this for at least a few days.
>>> Don't feel obligated to hold up for me.
>>> 
>>> On Wed, Jan 19, 2022, 9:04 AM Jacques Nadeau <ja...@apache.org> wrote:
>>> 
>>>> FYI, I'm trying to do a thorough review today (as much as possible with
>>>> patch this size).
>>>> 
>>>> On Wed, Jan 19, 2022, 4:36 AM Michael Mior <mm...@apache.org> wrote:
>>>> 
>>>>> Thanks for doing this Julian! I haven't been able to do a detailed
>> review,
>>>>> but from my skim of the PR, this looks like a nice improvement. I think
>>>>> it's always been a bit difficult for new Calcite developers to write
>> good
>>>>> tests, especially for new modules. So anything that helps that
>> experience
>>>>> is very welcome.
>>>>> 
>>>>> --
>>>>> Michael Mior
>>>>> mmior@apache.org
>>>>> 
>>>>> 
>>>>> Le mer. 17 nov. 2021 à 01:15, Vladimir Sitnikov <
>>>>> sitnikov.vladimir@gmail.com>
>>>>> a écrit :
>>>>> 
>>>>>> Jacques>This sounds like it will mean we will need to make
>> calcite-core
>>>>>> test artifacts available
>>>>>> 
>>>>>> Test artifacts publication is yet another anti-pattern just like "base
>>>>> test
>>>>>> class".
>>>>>> This change has been discussed:
>>>>>> https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1
>>>>>> 
>>>>>> If you want to depend on a class from tests, consider moving it to
>>>>> /testkit
>>>>>> module:
>>>>>> 
>>>>>> 
>>>>> 
>> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
>>>>>> 
>>>>>> Jacques>We should think about the rules around Kotlin
>>>>>> 
>>>>>> What happens in calcite-core/tests stays in calcite-core/tests :)
>>>>>> 
>>>>>> It is reasonable to assume that testkit module would have
>> dependencies,
>>>>>> and testkit would provide API that is usable from Java and other JVM
>>>>>> languages.
>>>>>> 
>>>>>> In that regard, Kotlin dependency in testkit is not much different
>> from
>>>>>> Quidem or commons-lang3.
>>>>>> Consumers might use Quidem if it fits just like they could use Kotlin
>>>>> if it
>>>>>> fits.
>>>>>> 
>>>>>> Vladimir
>>>>>> 
>>>>> 
>>>> 
>> 
>> 


Re: [DISCUSS] Refactoring tests

Posted by Gavin Ray <ra...@gmail.com>.
Thank you for doing this, after reading the overview these changes seem
like they will make a number of things easier related to testing.
Super useful too when you're trying to start building something with
Calcite but don't know it well enough to figure out how to put all the
pieces together yourself.

On Fri, Jan 21, 2022 at 3:57 PM Julian Hyde <jh...@gmail.com> wrote:

> If it helps you review, I have created a ’summary’ document with a
> description of the changes. It will become the commit message when I
> squash, rebase, and merge to master.
>
>
> https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md
> <
> https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md>
>
>
> Julian
>
>
> > On Jan 19, 2022, at 9:08 PM, Jacques Nadeau <ja...@apache.org> wrote:
> >
> > Unfortunately, the last minute attendance of the meetup today threw my
> > schedule off and I won't be able to look at this for at least a few days.
> > Don't feel obligated to hold up for me.
> >
> > On Wed, Jan 19, 2022, 9:04 AM Jacques Nadeau <ja...@apache.org> wrote:
> >
> >> FYI, I'm trying to do a thorough review today (as much as possible with
> >> patch this size).
> >>
> >> On Wed, Jan 19, 2022, 4:36 AM Michael Mior <mm...@apache.org> wrote:
> >>
> >>> Thanks for doing this Julian! I haven't been able to do a detailed
> review,
> >>> but from my skim of the PR, this looks like a nice improvement. I think
> >>> it's always been a bit difficult for new Calcite developers to write
> good
> >>> tests, especially for new modules. So anything that helps that
> experience
> >>> is very welcome.
> >>>
> >>> --
> >>> Michael Mior
> >>> mmior@apache.org
> >>>
> >>>
> >>> Le mer. 17 nov. 2021 à 01:15, Vladimir Sitnikov <
> >>> sitnikov.vladimir@gmail.com>
> >>> a écrit :
> >>>
> >>>> Jacques>This sounds like it will mean we will need to make
> calcite-core
> >>>> test artifacts available
> >>>>
> >>>> Test artifacts publication is yet another anti-pattern just like "base
> >>> test
> >>>> class".
> >>>> This change has been discussed:
> >>>> https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1
> >>>>
> >>>> If you want to depend on a class from tests, consider moving it to
> >>> /testkit
> >>>> module:
> >>>>
> >>>>
> >>>
> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
> >>>>
> >>>> Jacques>We should think about the rules around Kotlin
> >>>>
> >>>> What happens in calcite-core/tests stays in calcite-core/tests :)
> >>>>
> >>>> It is reasonable to assume that testkit module would have
> dependencies,
> >>>> and testkit would provide API that is usable from Java and other JVM
> >>>> languages.
> >>>>
> >>>> In that regard, Kotlin dependency in testkit is not much different
> from
> >>>> Quidem or commons-lang3.
> >>>> Consumers might use Quidem if it fits just like they could use Kotlin
> >>> if it
> >>>> fits.
> >>>>
> >>>> Vladimir
> >>>>
> >>>
> >>
>
>

Re: [DISCUSS] Refactoring tests

Posted by Julian Hyde <jh...@gmail.com>.
If it helps you review, I have created a ’summary’ document with a description of the changes. It will become the commit message when I squash, rebase, and merge to master.

https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md <https://github.com/julianhyde/calcite/blob/4885-test-fixtures/summary-of-calcite-4885.md> 

Julian


> On Jan 19, 2022, at 9:08 PM, Jacques Nadeau <ja...@apache.org> wrote:
> 
> Unfortunately, the last minute attendance of the meetup today threw my
> schedule off and I won't be able to look at this for at least a few days.
> Don't feel obligated to hold up for me.
> 
> On Wed, Jan 19, 2022, 9:04 AM Jacques Nadeau <ja...@apache.org> wrote:
> 
>> FYI, I'm trying to do a thorough review today (as much as possible with
>> patch this size).
>> 
>> On Wed, Jan 19, 2022, 4:36 AM Michael Mior <mm...@apache.org> wrote:
>> 
>>> Thanks for doing this Julian! I haven't been able to do a detailed review,
>>> but from my skim of the PR, this looks like a nice improvement. I think
>>> it's always been a bit difficult for new Calcite developers to write good
>>> tests, especially for new modules. So anything that helps that experience
>>> is very welcome.
>>> 
>>> --
>>> Michael Mior
>>> mmior@apache.org
>>> 
>>> 
>>> Le mer. 17 nov. 2021 à 01:15, Vladimir Sitnikov <
>>> sitnikov.vladimir@gmail.com>
>>> a écrit :
>>> 
>>>> Jacques>This sounds like it will mean we will need to make calcite-core
>>>> test artifacts available
>>>> 
>>>> Test artifacts publication is yet another anti-pattern just like "base
>>> test
>>>> class".
>>>> This change has been discussed:
>>>> https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1
>>>> 
>>>> If you want to depend on a class from tests, consider moving it to
>>> /testkit
>>>> module:
>>>> 
>>>> 
>>> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
>>>> 
>>>> Jacques>We should think about the rules around Kotlin
>>>> 
>>>> What happens in calcite-core/tests stays in calcite-core/tests :)
>>>> 
>>>> It is reasonable to assume that testkit module would have dependencies,
>>>> and testkit would provide API that is usable from Java and other JVM
>>>> languages.
>>>> 
>>>> In that regard, Kotlin dependency in testkit is not much different from
>>>> Quidem or commons-lang3.
>>>> Consumers might use Quidem if it fits just like they could use Kotlin
>>> if it
>>>> fits.
>>>> 
>>>> Vladimir
>>>> 
>>> 
>> 


Re: [DISCUSS] Refactoring tests

Posted by Jacques Nadeau <ja...@apache.org>.
Unfortunately, the last minute attendance of the meetup today threw my
schedule off and I won't be able to look at this for at least a few days.
Don't feel obligated to hold up for me.

On Wed, Jan 19, 2022, 9:04 AM Jacques Nadeau <ja...@apache.org> wrote:

> FYI, I'm trying to do a thorough review today (as much as possible with
> patch this size).
>
> On Wed, Jan 19, 2022, 4:36 AM Michael Mior <mm...@apache.org> wrote:
>
>> Thanks for doing this Julian! I haven't been able to do a detailed review,
>> but from my skim of the PR, this looks like a nice improvement. I think
>> it's always been a bit difficult for new Calcite developers to write good
>> tests, especially for new modules. So anything that helps that experience
>> is very welcome.
>>
>> --
>> Michael Mior
>> mmior@apache.org
>>
>>
>> Le mer. 17 nov. 2021 à 01:15, Vladimir Sitnikov <
>> sitnikov.vladimir@gmail.com>
>> a écrit :
>>
>> > Jacques>This sounds like it will mean we will need to make calcite-core
>> > test artifacts available
>> >
>> > Test artifacts publication is yet another anti-pattern just like "base
>> test
>> > class".
>> > This change has been discussed:
>> > https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1
>> >
>> > If you want to depend on a class from tests, consider moving it to
>> /testkit
>> > module:
>> >
>> >
>> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
>> >
>> > Jacques>We should think about the rules around Kotlin
>> >
>> > What happens in calcite-core/tests stays in calcite-core/tests :)
>> >
>> > It is reasonable to assume that testkit module would have dependencies,
>> > and testkit would provide API that is usable from Java and other JVM
>> > languages.
>> >
>> > In that regard, Kotlin dependency in testkit is not much different from
>> > Quidem or commons-lang3.
>> > Consumers might use Quidem if it fits just like they could use Kotlin
>> if it
>> > fits.
>> >
>> > Vladimir
>> >
>>
>

Re: [DISCUSS] Refactoring tests

Posted by Jacques Nadeau <ja...@apache.org>.
FYI, I'm trying to do a thorough review today (as much as possible with
patch this size).

On Wed, Jan 19, 2022, 4:36 AM Michael Mior <mm...@apache.org> wrote:

> Thanks for doing this Julian! I haven't been able to do a detailed review,
> but from my skim of the PR, this looks like a nice improvement. I think
> it's always been a bit difficult for new Calcite developers to write good
> tests, especially for new modules. So anything that helps that experience
> is very welcome.
>
> --
> Michael Mior
> mmior@apache.org
>
>
> Le mer. 17 nov. 2021 à 01:15, Vladimir Sitnikov <
> sitnikov.vladimir@gmail.com>
> a écrit :
>
> > Jacques>This sounds like it will mean we will need to make calcite-core
> > test artifacts available
> >
> > Test artifacts publication is yet another anti-pattern just like "base
> test
> > class".
> > This change has been discussed:
> > https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1
> >
> > If you want to depend on a class from tests, consider moving it to
> /testkit
> > module:
> >
> >
> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
> >
> > Jacques>We should think about the rules around Kotlin
> >
> > What happens in calcite-core/tests stays in calcite-core/tests :)
> >
> > It is reasonable to assume that testkit module would have dependencies,
> > and testkit would provide API that is usable from Java and other JVM
> > languages.
> >
> > In that regard, Kotlin dependency in testkit is not much different from
> > Quidem or commons-lang3.
> > Consumers might use Quidem if it fits just like they could use Kotlin if
> it
> > fits.
> >
> > Vladimir
> >
>

Re: [DISCUSS] Refactoring tests

Posted by Michael Mior <mm...@apache.org>.
Thanks for doing this Julian! I haven't been able to do a detailed review,
but from my skim of the PR, this looks like a nice improvement. I think
it's always been a bit difficult for new Calcite developers to write good
tests, especially for new modules. So anything that helps that experience
is very welcome.

--
Michael Mior
mmior@apache.org


Le mer. 17 nov. 2021 à 01:15, Vladimir Sitnikov <si...@gmail.com>
a écrit :

> Jacques>This sounds like it will mean we will need to make calcite-core
> test artifacts available
>
> Test artifacts publication is yet another anti-pattern just like "base test
> class".
> This change has been discussed:
> https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1
>
> If you want to depend on a class from tests, consider moving it to /testkit
> module:
>
> https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit
>
> Jacques>We should think about the rules around Kotlin
>
> What happens in calcite-core/tests stays in calcite-core/tests :)
>
> It is reasonable to assume that testkit module would have dependencies,
> and testkit would provide API that is usable from Java and other JVM
> languages.
>
> In that regard, Kotlin dependency in testkit is not much different from
> Quidem or commons-lang3.
> Consumers might use Quidem if it fits just like they could use Kotlin if it
> fits.
>
> Vladimir
>

Re: [DISCUSS] Refactoring tests

Posted by Vladimir Sitnikov <si...@gmail.com>.
Jacques>This sounds like it will mean we will need to make calcite-core
test artifacts available

Test artifacts publication is yet another anti-pattern just like "base test
class".
This change has been discussed:
https://lists.apache.org/thread/fz96p94h016p11g777otqntjxg2oxgh1

If you want to depend on a class from tests, consider moving it to /testkit
module:
https://github.com/apache/calcite/tree/0899e6c157632ba1c5369a942cfe2be15fb4ed9f/testkit

Jacques>We should think about the rules around Kotlin

What happens in calcite-core/tests stays in calcite-core/tests :)

It is reasonable to assume that testkit module would have dependencies,
and testkit would provide API that is usable from Java and other JVM
languages.

In that regard, Kotlin dependency in testkit is not much different from
Quidem or commons-lang3.
Consumers might use Quidem if it fits just like they could use Kotlin if it
fits.

Vladimir

Re: [DISCUSS] Refactoring tests

Posted by Jacques Nadeau <ja...@apache.org>.
I think it is a great idea to make the tests more accessible. A few
comments to consider in your work (no response expected):

   - I would vote to try to minimize the use of non-interface class
   inheritance , especially in downstream cases. For example, I would avoid a
   dominant path using base test subclasses in other projects. My experience
   on other similar projects is that using multi-level inheritance as a
   strategy makes things ultimately harder to compose.
   - This sounds like it will mean we will need to make calcite-core test
   artifacts available as part of distribution, something that doesn't happen
   currently
   <https://repo1.maven.org/maven2/org/apache/calcite/calcite-core/1.28.0/>.
   I was just trying to use SqlToRelTestBase.TesterImpl externally today and
   was disappointed to find out that maven doesn't hold the test
   classifier jars.
   - We should think about the rules around Kotlin, since it is used in the
   core test compilation cycle. Do projects need to depend on and/or adopt
   Kotlin to use these things?
   - I have zero opinion of AssertJ as relevant or a good idea.

My last thought is that I sometimes worry that we're quick to build bespoke
infrastructure within the project when there are good-enough primitives
that we could leverage that are more ecosystem idiomatic. A few examples
would be early json reading/writing, several relatively undocumented custom
plugins in the gradle build, ImmutableBeans, excessive use of unusual
reflection patterns, and use of Janino in non-performance-critical code
paths. I just hope we do our best to use ecosystem idiomatic solutions here
as much as makes sense. It improves approachability and helps when people
are struggling with problems (since usually there is more content out there
for people to figure things out on their own).

Again, super glad this work is getting done. Thanks for taking the
initiative Julian!



On Tue, Nov 16, 2021 at 2:27 PM Julian Hyde <jh...@apache.org> wrote:

> I am working on https://issues.apache.org/jira/browse/CALCITE-4885,
> "Fluent test fixtures so that dependent projects can write parser,
> validator and rules tests".
>
> I wanted to give you all a heads up, because it's going to change
> quite a few lines of code.
>
> Here's the problem I'm trying to solve. Calcite defines APIs such as
> RelRule, SqlOperator, and we encourage people to implement them in
> their projects (not necessarily contribute them back). But experience
> has shown that if you want to write, say, a planner rule, you'd better
> write some tests for it. And to write tests, you need to sub-class
> RelOptRulesTest.
>
> So, 4885 is about making it easier to write those kinds of tests.
>
> But - spoiler alert - subclassing the test classes isn't the way to
> go. Your subclass will inherit all of the tests from the base class.
> If you keep mutable state ("fixtures") in your test class, then
> maintaining that state gets messy as more tests add more state. We
> have added abstractions such as "tester" [1] but it's still pretty
> complicated.
>
> I am refactoring the test along the following lines:
>
> Test classes (e.g. RelOptRulesTest) contain tests but have no state.
> They have a "fixture()" method that returns a fixture. Often there is
> also a "sql(String sql)" method that just does
> "fixture().withSql(sql)".
>
> A fixture class (renamed from the helper classes called "Sql" in
> various tests) has a lot of methods that allow you to test things. But
> the only state in the fixture is a tester and a config. That state is
> immutable; each time you set a property, you create a new fixture that
> wraps a new copy of the config.
>
> A test config class is immutable and has lots of data fields.
>
> If the test uses reference files, the config will contain a
> DiffRepository. Subclasses can use a different DiffRepository (mapping
> to a different .xml file) but still use the same fixture
> implementation.
>
> A tester implements the nuts and bolts (e.g. parsing SQL, converting
> SQL to RelNode, planning). It has no state; the methods accept lots of
> parameters, such as whether decorrelation is enabled, from the config.
> There's usually only one implementation of tester, but you can
> override for special reasons (e.g. an implementation of the parser
> tester that converts the AST back to SQL and tries to parse it a
> second time).
>
> With these changes, people will be able to create a test that
> instantiates a fixture, calls some methods to configure it, and then
> calls some methods to run their test. See FixtureTest and Fixtures
> [2]. They can do that in any class, not necessarily a subclass of an
> existing Calcite test.
>
> Our test framework is not covered by semantic versioning. People in
> dependent projects who depend on our test framework may have to fix up
> their tests when they upgrade. It shouldn't be too bad.
>
> In the bug Vladimir suggested that we take this opportunity to move
> from Hamcrest matchers to AssertJ. I disagree. I'm not convinced that
> AssertJ is so much better that moving to it is worth the disruption.
> And in any case, this change is about figuring out the lifecycle (e.g.
> how do I configure my test to add and remove rules from the planner,
> when the planner doesn't exist until I'm half way through my test) and
> I don't think AssertJ helps with that.
>
> I am going to make fixtures, configs and testers top-level classes
> (i.e. not inner classes). It makes them easier to extend.
>
> I might make fixtures into interfaces whose methods all have defaults.
> Then people can easily subclass fixtures; they could even inherit from
> multiple fixtures.
>
> Let me know if you have ideas or concerns. I recommend that people who
> have written tricky tests (e.g. TopDownOptTest) track this
> development.
>
> Julian
>
> [1]
> https://github.com/apache/calcite/blob/4b1e9ed1a513eae0c873a660b755bb4f27b39da9/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java#L568
>
> [2]
> https://github.com/julianhyde/calcite/commit/0286f78b0db0e364f3225f004b32853de2685a39
>

Re: [DISCUSS] Refactoring tests

Posted by Vladimir Sitnikov <si...@gmail.com>.
Julian,

Thanks for taking time, and working on this.

"Fixture" is a too broad term, and I do not mean we should replace it
completely with AssertJ.

What I mean is that AssertJ allows creating *discoverable* assertions.
Hamcrest assertions are hard to create and hard to discover in IDE.

---

Re test code implementations, we junit5 extensions would likely be useful.
For instance


@ExtendWith(CalciteParserExtensions.class)
@WithLex(BACK_TICKS)
class MyParserTest {
   void invalidSqlFails(SqlParserFixture sql) { // <-- injected by extension
.....

In other words, it does not mean fixture (whatever it means) must be 100%
junit5.
What I mean, junit5 extensions could simplify writting calcite tests by
making fixture confuguration declarative, and injecting the configured
object as test method argument.

Vladimir