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

pytest-bdd parse step definition matcher #206

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

Conversation

kieran-ryan
Copy link
Member

🤔 What's changed?

  • Support the parse step definition matcher of pytest-bdd - which is also used by behave; both Python frameworks

⚡️ What's your motivation?

🏷️ What kind of change is this?

  • ⚡ New feature (non-breaking change which adds new behaviour)

♻️ Anything particular you want feedback on?

📋 Checklist:

  • I agree to respect and uphold the Cucumber Community Code of Conduct
  • I've changed the behaviour of the code
    • I have added/updated tests to cover my changes.
  • Users should know about my change
    • I have added an entry to the "Unreleased" section of the CHANGELOG, linking to this pull request.

This text was originally generated from a template, then edited by hand. You can modify the template here.

@kieran-ryan kieran-ryan added the ⚡ enhancement Request for new functionality label Apr 23, 2024
@kieran-ryan kieran-ryan self-assigned this Apr 23, 2024
@neskk
Copy link

neskk commented Sep 21, 2024

Hello @kieran-ryan,

Found some time to help test this PR.

  • I've added some pytest-bdd parser step definitions to the StepDefinitions.py test file, but I have the ExpressionBuilder tests failing.
  79 passing (1s)
  22 failing

  1) ExpressionBuilder
       with NodeParserAdapter
         builds parameter types and expressions from tsx source:

      AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
+ actual - expected

+ []
- [
-   'a {uuid}',
-   'a {date}',
-   'a {planet}',
-   /^a regexp$/,
-   "the bee's knees"
- ]
  • Since my node/vs-code development experience is very limited, I don't know what's the best procedure to test this or contribute with unit-tests. I would appreciate some help. Will the support for this kind of pytest-bdd syntax be hard to merge?

@neskk
Copy link

neskk commented Dec 12, 2024

Hello @vianney-g, did you manage to test this locally? Are you using pytest-bdd parser syntax:

@given(parsers.parse("a stub with {stub_id} exists"))
@given(parsers.parse("a stub exists with:" + os.linesep + "{stub_str}"))

I wish to have support for pytest-bdd parser syntax: https://pytest-bdd.readthedocs.io/en/stable/#step-arguments, including support for custom param types.

I can try to run some experiments locally, I just need to grab your changes and install the extension on my dev environment.

@vianney-g
Copy link

Hello @vianney-g, did you manage to test this locally? Are you using pytest-bdd parser syntax:

@given(parsers.parse("a stub with {stub_id} exists"))
@given(parsers.parse("a stub exists with:" + os.linesep + "{stub_str}"))

I wish to have support for pytest-bdd parser syntax: https://pytest-bdd.readthedocs.io/en/stable/#step-arguments, including support for custom param types.

I can try to run some experiments locally, I just need to grab your changes and install the extension on my dev environment.

hi @neskk , ty for your interest.

I was just facing the bug with pytest_bdd and I was wondering how to fix it. Then I discovered your PR. Then I realized it may not match all the cases. I think the query should match the following steps definitions:

import pytest_bdd
from pytest_bdd import given, parsers, when, then
from pytest_bdd.parsers import parse


@pytest_bdd.given(parse("a stub with stub_id exists"))
@given(parse("a stub with {stub_id} exists"))
@when(parsers.parse("a stub with {stub_id} exists"))
@then(parsers.parse("a stub with {stub_id} exists" + " then"))
def test_stub_exists(stub_id):
    assert stub_id == "stub_1"
    return stub_id


@not_a_step(parse("a stub with {stub_id} exists"))
def test_not_match(stub_id):
    assert stub_id == "stub_1"
    return stub_id

Please forget my suggestions above. I made some tests locally, and I think the following approach is better to match all the cases (I am not a pro of treesitter queries, I am just playing with):

(decorator 
  (call
    arguments: 
    (argument_list
      (call
	arguments:
	(argument_list
	  [(_) @pattern]
	  ) @args
	) @parse
      )
    ) @decorator
  (#match? @decorator "given|when|then")
  (#match? @parse "parse")
  )

image

@neskk
Copy link

neskk commented Dec 13, 2024

I never looked into treesitter and the TypeScript/node.JS environment is still a bit foreign to me.
This MR is from @kieran-ryan, but I haven't seen him around for a while.
I have some more test cases we should use to validate correct parsing, I will try to test them locally and post my result with your changes.

@vianney-g
Copy link

You can adapt the python test file to reflect the different approaches. This patch works for me:

--- a/src/language/pythonLanguage.ts
+++ b/src/language/pythonLanguage.ts
@@ -95,46 +95,28 @@ export const pythonLanguage: Language = {
     `(decorated_definition
       (decorator
         (call
-          function: (identifier) @method
           arguments: (argument_list (string) @expression)
-        )
+        ) @method
       )
       (#match? @method "(given|when|then|step)")
     ) @root`,
     // pytest-bdd
-    `(decorator
-      (call
-        function: (identifier) @annotation-name
-        arguments: (argument_list
-          (call
-            function: (attribute) @parser
-            arguments: (argument_list
-              [
-                (string) @expression
-              ]
-            )
-          )
-        )
-      )
-      (#match? @annotation-name "given|when|then|step")
-      (#match? @parser "parser")
-    ) @root`,
-    `(decorator
-      (call
-        function: (identifier) @annotation-name
-        arguments: (argument_list
-          (call
-            function: (attribute) @parser
-            arguments: (argument_list
-              [
-                (binary_operator) @expression
-              ]
-            )
-          )
-        )
+    `(decorated_definition
+      (decorator
+        (call
+          arguments:
+          (argument_list
+            (call
+              arguments:
+              (argument_list
+                [(_) @expression]
+              )
+            ) @args
+          ) @parse
       )
-      (#match? @annotation-name "given|when|then|step")
-      (#match? @parser "parser")
+    ) @annotation-name
+    (#match? @annotation-name "given|when|then|step")
+    (#match? @parse "parse")
     ) @root`,
   ],
   snippetParameters: {
diff --git a/test/language/testdata/python/StepDefinitions.py b/test/language/testdata/python/StepDefinitions.py
index cc61457..406e17e 100644
--- a/test/language/testdata/python/StepDefinitions.py
+++ b/test/language/testdata/python/StepDefinitions.py
@@ -1,19 +1,23 @@
 """Port of givens for testdata."""

 from behave import step, given, when, then
+from pytest_bdd.parser import parse
+from pytest_bdd import parser

+import pytest_bdd

-@step("a {uuid}")
+
+@step(parse("a {uuid}"))
 def step_given(context, uuid):
     assert uuid


-@given("a {date}")
+@given(parser.parse("a {date}"))
 def step_date(context, date):
     assert date


-@when("a {planet}")
+@pytest_bdd.when("a {planet}")
 def step_planet(context, planet):
     assert planet

@neskk
Copy link

neskk commented Dec 16, 2024

Thanks for sharing the patch with your changes @vianney-g. The diff is against the main branch or the branch of this MR?

Is your test flow like, run npm install, npm test, and then open a VSCode instance on a pytest-bdd project?
I'm having an issue (Win11 node v.18.20.5) getting the library to install (npm install):

Compiling node_modules\tree-sitter-go inside docker
Failed to build wasm for node_modules\tree-sitter-rust: Command failed: node_modules/.bin/tree-sitter build-wasm node_modules\tree-sitter-rust --docker
'node_modules' is not recognized as an internal or external command,
operable program or batch file.

@vianney-g
Copy link

Hey @neskk ! This is a patch for the branch of this PR.

I can run the tests with npm test, and it works. The compilation step ran successfully on my side. I am on my phone now, I will check again with my laptop if I did something special to make it work.

@vianney-g
Copy link

So, I confirm that everything worked well on my side with npm install && npm test. I am sorry, but I don't understand what is going wrong on your side. I am on node v18.17.1 on a Linux machine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⚡ enhancement Request for new functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pytest-BDD parse matcher step definitions
3 participants