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

Some y_testing suggestions #157

Open
Southclaws opened this issue Feb 9, 2017 · 14 comments
Open

Some y_testing suggestions #157

Southclaws opened this issue Feb 9, 2017 · 14 comments

Comments

@Southclaws
Copy link
Contributor

Southclaws commented Feb 9, 2017

I've been using y_testing lately (not sure if there are any other unit testing frameworks for Pawn) and it's pretty useful but I thought I'd raise an issue about some of the things I think it's missing:

  • Assertions for floating points that allows inaccuracies - similar to Python's assertAlmostEqual
  • Some kind of callback testing - this function should trigger callback X within Y seconds - inlines?
  • A pre and post func entire test suite instead of each test case - for singular dependencies such as connecting to a database once for the entire suite instead of connecting and disconnecting for each test.
  • This is probably not possible to just add-in but it would be neat to print out the expected/actual values if a test fails ("FAIL: expected 43 got 0") - you'd probably have to build individual per-type assertion functions for this, would be useful though!

I'll PR any improvements if I get around to it!

@Y-Less
Copy link
Member

Y-Less commented Feb 9, 2017

I like those, though I'm not sure how easy some of them would be:

  • Yes.
  • Currently a test is a wholy self-contained unit. That would require being able to defer deciding if the whole test succeeded or not for a while. Not impossible, just going to take some thinking and reorganisation.
  • I've thought about that as well. I wrote a similar system for C++ to do (can't remember the syntax any more):
TEST_SUITE(Network)
{
    INIT()
    {
        // Open the database.
    }
    TEST(One)
    {
    }
    CLOSE(One)
    {
        // Something after just test one.
    }
    TEST(Other)
    {
    }
    CLOSE()
    {
        // Something after the whole suite.
    }
}

Maybe I could achieve something similar now, with either y_inline (though I don't like the idea of pulling in a high-level dependency for y_testing - it makes testing y_inline (which really needs it) hard), or just regular scopes (the C++ version I know was done with namespaces, so was fully hierarchical).

  • You are right that it would need specialised functions, but I've wanted this so many times myself I don't know why it doesn't exist already! Keep the generic ASSERT for the current pass/fail tests and add things like ASSERT_EQUAL, ASSERT_SAME (or something else for ASSERT_STRING_EQUAL but not that long), ASSERT_SIMILAR (for your float case) etc. The underlying assert functions actually already format their output, but exactly zero macros use that feature. In terms of writing, I'd probably just group this with your first suggestion (and of the four, it's not the hardest, unless you mean in a totally generic sense).

@Southclaws
Copy link
Contributor Author

Southclaws commented Feb 9, 2017

I probably should have elaborated a bit on the callback testing since that's my most complex suggestion and I had some ideas on how it should work (it's always a difficult problem, I'm not too familiar with how other async languages handle that sort of stuff, like Go and JavaScript, I've actually just finished writing a test case for work in Go which was a monster of a task requiring lots of channel waiting and extra stuff on top of the simple underlying event code)

One thought I had was to use timers (which also brings in the possibility to test timeouts for failed connections) - fire a timer saying "Expect some assertion to be true in 5 seconds", do the MySQL/Redis/HTTP/whatever call and on the callback call a y_testing "callback fired, here's the assertion" function then the timer I mentioned at the start checks some internal value for the assertion result.

The main reason for me suggesting this is because my Redis plugin test case currently looks like this, a bit of a mess and if the test fails it's disconnected from the y_testing system so the failure doesn't count as a failure!

At the very least, it could be an interesting problem to solve anyway!

@Y-Less
Copy link
Member

Y-Less commented Feb 9, 2017

I'm not sure what you mean by "if the test fails it's disconnected from the y_testing system so the failure doesn't count as a failure!". Also, I remembered that PTests have a sort of delay to them (not ideal and would need refining) in that they do something and ask the user for feedback, but that means that they are purely sequential.

@Southclaws
Copy link
Contributor Author

Southclaws commented Feb 10, 2017

I meant the test result is collected in a deferred function so y_timers has already finished counting up pass/fails in the Test: function.

@Y-Less
Copy link
Member

Y-Less commented Feb 10, 2017

Ahh, yes I see.

@Misiur
Copy link
Collaborator

Misiur commented Sep 25, 2017

Alright, I think I'm enough pissed off with testing stuff in client that I want to approach async testing now. Really ghetto implementation which I have in mind would be something like this:
Invasive test (as in, requires test code in function which is to be tested), something like

FunctionToTest(some, params #if async_test ,&done #endif)
{
  inline DoesntMatter()
  {
    Group_GetPlayer(SomeTestGroup, 0, true);
    #if async_test
        done = true;
    #endif
  }
}

// (...)
new done = false, Timer:toBeKilled;
AsyncTestStart:TestWhatever()
{
  FunctionToTest(1, 2, done);
  toBeKilled = repeat AsyncChecker();
}

timer AsyncChecker[10]()
{
  if (done) {
    stop toBeKilled;
    AsyncTestStop:TestWhatever();
  } 
}

AsyncTestStop:TestWhatever()
{
  // whatever
  ASSERT(!!Group_GetPlayer(SomeTestGroup, 0));
}

I come from the weird land of JS, don't judge my lack of ability to came up with a solution in a single-threaded application.

Any opinions welcome

Edit: Duh, JS (at least node) is single-threaded too, but I guess you can't implement async/await/Promise/generators in PAWN

@Y-Less
Copy link
Member

Y-Less commented Sep 25, 2017

Edit: Duh, JS (at least node) is single-threaded too, but I guess you can't implement async/await/Promise/generators in PAWN

Funny you should say that!

And Slice and I have been discussing the rest for a few weeks now...

@Misiur
Copy link
Collaborator

Misiur commented Sep 25, 2017

Damn! I don't want to dissapoint myself, but maybe something like redux-saga could be achieved.

Off-topic: Where you guys hang out? PM on forums?

@oscar-broman
Copy link

About 2 meters from each other.

@Y-Less
Copy link
Member

Y-Less commented Sep 25, 2017

Damn! I don't want to dissapoint myself, but maybe something like redux-saga could be achieved.

No promises, but that was exactly Slice's idea.

About 2 meters from each other.

Fancy seeing you here!

@Y-Less
Copy link
Member

Y-Less commented Sep 25, 2017

http://forum.sa-mp.com/showpost.php?p=3695017

Shuffled around, got some proper desks, and extended the work since then - but he is the main reason I still dabble at all after my infamous exit!

@oscar-broman
Copy link

I should probably do some Pawn coding.. It's been too long.

If something like redux-saga could be made then one could easily script an amazing event system that covers the entire SA-MP API.

@Misiur
Copy link
Collaborator

Misiur commented Sep 25, 2017

04/05/2016

I see your teamwork gave some great results if you're still going strong!

PAWN is like crack, I should probably move on (and focus on my brother's and mine GTA knockoff (I even had a crazy idea to use PAWN as a scripting language there too and unify it with SA-MP API)), but I keep checking forums and responding to people's issues here

(sorry Southclaws for notification spam)

@Y-Less
Copy link
Member

Y-Less commented Sep 25, 2017

I should probably move on

Yeah good luck with that...

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

4 participants