Skip to content
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

WIP: Fusion Tests inside of Fusion #3572

Closed
wants to merge 3 commits into from

Conversation

mhsdesign
Copy link
Member

@mhsdesign mhsdesign commented Jan 17, 2022

I was inspired by this comment: #2729 (comment)
and started this WIP idea...

Currently all functional fusion tests still need to be registered manually in the corresponding php test class and also the expected results are located on the php site. This PR attempts to put this closer to fusion ... in fusion.

The idea is we leverage php units dataprovider and parse the fusion beforehand then look for all paths on the first level who end with 'Test' and yield a configuration (which is generated only from the ast - not at runtime)

run the tests via the usual:

./bin/phpunit -c ./Build/BuildEssentials/PhpUnit/FunctionalTests.xml ./Packages/Neos/Neos.Fusion/Tests/Functional/WithinFusionTests/FusionFixturesTest.php

test generation in more detail:

get all first level paths which end with 'Tests' or which are a Neos.Fusion.Testing:TestCase
it can have multiple test and fusion data providers - which will be in mixed combinations evaluated.

return values of @beforeRender and @afterRender are ignored, their purpose is to call methods on the context objects:

  • self - the instance of this testcase
  • view - the instance of the used view
  • result - return value of the provider accessible in @afterRender
what_im_testing_here_test {
  @test.1 {
    @beforeRender = ${ view.assign('foo', 123) && self.expectException('Foo\Class') }
  }
  @test.2 {
    @beforeRender = ${ view.assign('foo', 'hi') }
    @afterRender = ${ self.assertSame(actual, 'hi') }
  }

  @fusion.1 = Foo:BarWhichTrowsWhenAnIntGivenElseReturns {
    foo = ${ foo }
  }
}

php unit dataproviders

using dataproviders has the advantage, that each fusion test is treated separately from another fusion tests, and so if one test fails - not everything breaks.

Also filtering with --filter works:

./bin/phpunit -c ./Build/BuildEssentials/PhpUnit/FunctionalTests.xml ./Packages/Neos/Neos.Fusion/Tests/Functional/WithinFusionTests/FusionFixturesTest.php --filter "apply"

exception messages when one test fails are also fairly readable:
...FusionTestsFusion\FusionTestsFusionTest::assertFusionRendersAsExpected with data set "dataStructureTest.nestingWithNonExistingChildObject with: scenario[1] provider[1]"

how to write the new tests?

i put some working examples in the Fixtures/Fusion/FusionTestsFusion/ dir.
you can run those from the flow root with:

./bin/phpunit -c ./Build/BuildEssentials/PhpUnit/FunctionalTests.xml ./Packages/Neos/Neos.Fusion/Tests/Functional/FusionObjects/FusionTestsFusion

Checklist

  • Code follows the PSR-2 coding style
  • Tests have been created, run and adjusted as needed
  • The PR is created against the lowest maintained branch

... what do you say?
i did create two new folders and so as this is WIP and just a demo ^^

see #3594

@mhsdesign
Copy link
Member Author

Extracted the testcase into own Package Neos.Fusion:Testing as you suggested @mficzel

@mficzel
Copy link
Member

mficzel commented Feb 1, 2022

@mhsdesign sorry for sidetracking this with the idea to separate the testing into an extra package. Just noticed how much changes would be needed with almost non existing gain in neos/flow-development-collection#2683.

I am sorry for causing extra work and agree that the base testcase should be in tests in the neos/fusion package.

@mhsdesign
Copy link
Member Author

mhsdesign commented Feb 6, 2022

Sure we can keep it in Neos.Fusion ;)

how can we proceed?

But before i move this again i would like to know how we can proceed. Maybe we can roll this out with 8.0 - we dont have to rewrite all tests but id like that we then have agreed on a syntax and implementation.

in terms of syntax and implementation id like to abstact as less as possible (eg. make the testCase accessible in eel)

or as i wrote in slack:

[...] it really just boils down to 100 lines (since im using phpunit dataprovider) https://github.com/neos/neos-development-collection/blob/d48efacc6dea63b4db6cd3816274dd7696752148/Neos.Fusion/Tests/Functional/FusionObjects/FusionTestsFusion/FusionTestsFusionTest.php

and i preferred my proposed way of working with 'before' and 'after' hooks, and accessing the testcase (self) and the view directly in eel/fusion - as this abstracts less, and we know how to work with php unit.

i also made the Implementation with the most logic packed php fusion test in mind


so we can easily test more complex stuff like this or just a simple in out.

@mhsdesign mhsdesign closed this Feb 6, 2022
@mhsdesign mhsdesign reopened this Feb 6, 2022
@mficzel
Copy link
Member

mficzel commented Feb 7, 2022

Added an issue for tracking on the release boards, no pressure to finish this for Neos 8.0 as this is a clear feature that can be added later aswell. Would still be nice if we would manage to get this in.

@mhsdesign
Copy link
Member Author

arent we basically trying to build our own behat? - why not use it directly ^^

@kitsunet
Copy link
Member

arent we basically trying to build our own behat? - why not use it directly ^^

Sounds a bit like it, I agree...

@mficzel
Copy link
Member

mficzel commented Mar 16, 2022

Would be fine with that aswell

@mhsdesign
Copy link
Member Author

mhsdesign commented Mar 16, 2022

but behat files wont give us fancy fusion syntax highlighting ... (for inline fusion snippets)

edit: they do, if one writes it like:

"""fusion

foo = "bar"

"""

@mhsdesign
Copy link
Member Author

Looks better so far than my totally in fusion approach:

Feature: Fusion
  As a developer i want to write Fusion because Fusion is cool

  Scenario: Simple value
    Given I have this Fusion
      """
      include: resource://Neos.Fusion/Private/Fusion/Root.fusion
      root = Neos.Fusion:Value {
        value = "abc"
      }
      """
    Then I expect to have the following result for path "root"
      """
      abc
      """

  Scenario: Simple array
    Given I have this Fusion
      """
      include: resource://Neos.Fusion/Private/Fusion/Root.fusion
      root = Neos.Fusion:DataStructure {
        foo = "bar"
      }
      """
    Then I expect to have the following json array for path "root"
      """
      {
        "foo": "bar"
      }
      """

@mficzel
Copy link
Member

mficzel commented Mar 20, 2022

I agree, that looks really nice and is really easy to understand.

@mhsdesign
Copy link
Member Author

i will close this pr, and make a new WIP one based on behat.

(just too keep the original idea and code seperately)

@mhsdesign mhsdesign closed this Mar 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Write better Fusion tests (with behat)
3 participants