Skip to content

Add more unit tests for PyButton and BaseEvalElement#711

Merged
marimeireles merged 4 commits into
pyscript:mainfrom
FabioRosado:fr/jest
Aug 26, 2022
Merged

Add more unit tests for PyButton and BaseEvalElement#711
marimeireles merged 4 commits into
pyscript:mainfrom
FabioRosado:fr/jest

Conversation

@FabioRosado

Copy link
Copy Markdown
Contributor

This PR is part of the effort to increase test coverage (#679). Two new test files were added:

  • one for PyButton
  • one for BaseEvalElement

I wonder if this is the right approach to testing each component and perhaps some internals. Many of these tests are just asserting default behaviours and checking that things changed as we expect when calling functions.

Please let me know if you would prefer to test these differently or if you think it's good then I'll keep writing tests for the other files 😄

@marimeireles marimeireles left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great effort!
Thank you so much @FabioRosado :)
My comment on the test with the error is because I'm thinking well, mostly about maintainability... Should we create tests that we know it fails?
@antocuni will probably have an input here as he introduced this discussion on our previous PR.
But if anyone else wants to chime in, please!

Comment on lines +15 to +32
it('BaseEvalElement instantiates correctly', async () => {
expect(instance).toBeInstanceOf(BaseEvalElement);
});

// TODO: This test is a bit silly, but the idea is to keep it here until we fix this
// issue
it("should fail with: Cannot use 'in' operator to search for 'runPythonAsync' in undefined", async () => {
let thrownError;
let expectedTypeError = new TypeError("Cannot use 'in' operator to search for 'runPythonAsync' in undefined");
try {
instance.runAfterRuntimeInitialized(async () => {
return;
});
} catch (error) {
thrownError = error;
}
expect(thrownError).toEqual(expectedTypeError);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering there's no other way to test this functionality? Or to ignore this error?

@FabioRosado FabioRosado Aug 25, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great question(s)!

We could mock runAfterRuntimeInitialized similar to what I've done in pybutton.test.ts so this exception won't impact the tests.

This test was added mostly because I was poking at the exception and trying to figure out what's happening and thought it could be good to include in the PR so that when we fix the issue, his test will fail and we can remove it. Maybe that's a bad idea? 😄

Happy to remove it if you think is best

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be the best approach for now. But we can get back to it once Antonio is back on vacation and I hear what he has to say =)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was added mostly because I was poking at the exception and trying to figure out what's happening and thought it could be good to include in the PR so that when we fix the issue, his test will fail and we can remove it. Maybe that's a bad idea?

I think it's a very good idea! +1

Comment thread pyscriptjs/tests/unit/pybutton.test.ts
@FabioRosado

Copy link
Copy Markdown
Contributor Author

Thank you, if this seems like a good approach I'll start adding more tests to cover other parts 😄

@marimeireles

Copy link
Copy Markdown
Contributor

Yeah sure! This is a great approach.
Thanks Fabio. =)

@marimeireles

Copy link
Copy Markdown
Contributor

Also, seems like there are some small issues with the tests.
I'm wondering if this 4 import { pyodideLoaded } from '../../src/stores'; error is the same one as we were debugging together the other day @madhur-tandon, with your tests? (That you had to create a mockup, etc...)

@FabioRosado

Copy link
Copy Markdown
Contributor Author

I think this might be happening because I haven't merged main into this branch yet 🤔

Let me try doing that and run the tests again just to see

@madhur-tandon

Copy link
Copy Markdown
Contributor

Hi @FabioRosado you might wanna rebase on main

@FabioRosado

FabioRosado commented Aug 25, 2022

Copy link
Copy Markdown
Contributor Author

Thanks Madhur and Mariana! I've rebased main into the branch and fixed the imports, I've also marked the integration test test_repl as xfail here since it seems this test has been failing very often in CI

@marimeireles

Copy link
Copy Markdown
Contributor

Thanks for the work Fabio! ✨
Will review it now 😊

@marimeireles

Copy link
Copy Markdown
Contributor

I was trying to reproduce the test_repl error locally but can't.
Which makes me wonder if there's something related to our CI? Like do we need more time to run these tests?
Other than that! 🎉
Thank you Fabio! :)

@marimeireles marimeireles merged commit 9de1545 into pyscript:main Aug 26, 2022
@FabioRosado

Copy link
Copy Markdown
Contributor Author

Thank you Mariana!
Yeah it seems to be flaky at times, I've installed pytest-repeat and did 20 runs of the reply test and it failed 4 times, I'm wondering if sometimes the repl doesn't return quick enough

@antocuni antocuni left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late review! @FabioRosado thank you for this PR, I'm always happy when I see new tests :)

To answer your question:

I wonder if this is the right approach to testing each component and perhaps some internals.
[cut]
Please let me know if you would prefer to test these differently

JS unit tests are good, and our current situation is so bad that every progress in this area is very welcome.
Personally, I think that integration tests are more important, though.

In my view, unit tests are more an internal tool which is useful for us to ensure the correctness and quality of our code.

On the other hand, integration tests represent our contract with the end users: they declare (and check!) what happens when you use pyscript in your HTML page and that when we refactor the code we don't accidentally break legitimate usage of it. For every user-visible functionality of pyscript, we surely want to have at least one integration test which checks that it keep working as expected.

In the long run both are important, but if I have to choose, in the short term I'd probably prefer to increase the coverage of integration tests. But this is just my personal opinion which might or might not be shared by the rest of the team

}
expect(thrownError).toEqual(expectedTypeError);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disclaimer: this is literally the first time ever which I see a Javascript/Jest unit test so I don't really know about the idioms. If I understand correctly, this is basically the equivalent of pytest.raises, isn't it?
Is it there a more direct way to do it? A quick googling tells me about expect().toThrow() but I don't really know whether it applies here.

Also, small nitpick: it would have been nicer to put the issue number in the comment, so that it will be easier to understand why the test fails once the issue it's fixed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah my idea was to write a test similar to pytest.raises 😄

Oh I didn't knew about the toThrow check, I'm still getting used writing js/jest tests haha
That's a good point that didn't occur to me. I'm planning to write more tests over the weekend so I'll make sure to add the issue number on this one 😄

Comment on lines +15 to +32
it('BaseEvalElement instantiates correctly', async () => {
expect(instance).toBeInstanceOf(BaseEvalElement);
});

// TODO: This test is a bit silly, but the idea is to keep it here until we fix this
// issue
it("should fail with: Cannot use 'in' operator to search for 'runPythonAsync' in undefined", async () => {
let thrownError;
let expectedTypeError = new TypeError("Cannot use 'in' operator to search for 'runPythonAsync' in undefined");
try {
instance.runAfterRuntimeInitialized(async () => {
return;
});
} catch (error) {
thrownError = error;
}
expect(thrownError).toEqual(expectedTypeError);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was added mostly because I was poking at the exception and trying to figure out what's happening and thought it could be good to include in the PR so that when we fix the issue, his test will fail and we can remove it. Maybe that's a bad idea?

I think it's a very good idea! +1

@FabioRosado

Copy link
Copy Markdown
Contributor Author

Thank you for the review Antonio, that makes sense, I'll keep adding both integration tests and unit ones too now that I know this is a good approach 😄

@FabioRosado FabioRosado deleted the fr/jest branch August 31, 2022 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants