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

Parse tests out of scripts #1

Open
bitwes opened this issue Aug 16, 2016 · 6 comments
Open

Parse tests out of scripts #1

bitwes opened this issue Aug 16, 2016 · 6 comments

Comments

@bitwes
Copy link

bitwes commented Aug 16, 2016

I came across your repo when searching for godot typeof examples. I wasn't sure how else to share this, so sorry for using an issue. I've created my own unit testing tool as well. I'm really interested in your approach. I thought I'd share with you how I parse out the tests from the files. Here's the code.

#-------------------------------------------------------------------------------
#Parses out the tests based on the _test_prefix.  Fills the _tests array with
#instances of OneTest.
#-------------------------------------------------------------------------------
func _parse_tests(script):
    var file = File.new()
    var line = ""
    var line_count = 0

    file.open(script, 1)
    while(!file.eof_reached()):
        line_count += 1
        line = file.get_line()
        #Add a test
        if(line.begins_with("func " + _test_prefix)):
            var from = line.find(_test_prefix)
            var len = line.find("(") - from
            var new_test = OneTest.new()
            new_test.name = line.substr(from, len)
            new_test.line_number = line_count
            _tests.append(new_test)

    file.close()

You should be able to adapt this, but here's a few notes

  • The script parameter is the path to the test script (i.e. 'res://unit_tests/test_this_thing.gd')
  • OneTest is a simple struct class to hold info about each test. I keep an array of them (_tests) and then loop through them later calling them using call.
  • test_prefix holds 'test' in it by default. I just used a variable in case someone wanted to use something else.

I've written 46 test scripts with about 1000 tests and this logic has worked just fine. Hope it helps.

If you're interested, my testing tool can be found at https://bitbucket.org/bitwes/gut. I'm working on a 3.0 version now and will be moving it to github when it is done (by the end of the week at the latest).

@groboclown
Copy link
Owner

Thanks for the suggestion. That's an interesting approach - to actually parse out the script itself. I never like the idea of needing to explicitly call out the list of test functions, so this would be a big help.

The function parsing would need to be a bit more flexible, because for proper grammar handling it would need to be able to deal with spaces correctly (e.g. "func test_a (x)"), but that can easily be dealt with through regular expressions. I don't think that gdscript has any situations where there can be free-form text with "func" at the start of a line, so this would work.

A further simplification would be to have the base test class call "get_script()" in the _init function, and parse the text from the returned string. That way the test class could override this behavior if it wanted to (such as to force tests to run in a specific order, or if the user just wants to be contrary and not use the naming convention).

@bojidar-bg
Copy link

What about simply using get_method_list for get the methods, then parse it instead? 😄

@groboclown
Copy link
Owner

It's too easy. That's just what they're expecting us to do.

No, reading the get_method_list and calling the methods that start with test_ is the better option.

@bitwes
Copy link
Author

bitwes commented Aug 16, 2016

Either I didn't know about it or the methods don't come back in the order they are in the file. That's all speculation though, I wrote that's long time ago. I do spit out the line number for the test when a test fails though, which is handy when dealing with a test script with a lot of tests.

@groboclown
Copy link
Owner

As a historical note, the Godot 1.x code line didn't provide a get_method_list function, so that would explain why we went through these pains to find the list of tests to run. With 2.x, that's now solved.

@groboclown
Copy link
Owner

I've updated the unit_test component to how support auto-detection of test methods, as well as some other improvements, such as more matchers, a new check method, more flexibility in the error reporting, and better test case skipping.

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

No branches or pull requests

3 participants