-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Create NodeMCU test system NTest based on gambiarra #2984
Conversation
NOTE: The readme is not yet updated. |
It'd be really nice to be able to announce the existence of our test framework by the next release. @HHHartmann have you had time to weigh the pros and cons of mispec and gambiarra? Would you mind doing a bit of compare-and-contrast for those of us not familiar? |
@HHHartmann Would you be opposed to just using |
Having played a little with gambiarra now, I think I like it, except that we don't know how many tests we're going to run, which makes things a little sad from TAP's perspective. We could require the tests themselves to generate the TAP plan message of "TAP 1..34" (e.g.) (which might be a perfectly OK thing to do, and is in fact kind of typical of TAP-based frameworks; it's just that because myspec build up the whole test table up front, it was easy to count). |
I am also in favor of gambiarra. I already added some more functionality to it and there might be more. I am also working on first async tests which I will commit soon. |
I don't mind renaming the directory. Just thought that it matches the remaining directories containing lua code. |
Sorry to be dense in communication. FWIW, your English seems better than mine, and I'm a monolingual dunce. ;) TCL is the Tool Command Language and is used by I think (but I'm open to suggestions) that it makes sense to put all our core tests in a single directory, regardless of their implementation language, and I, lacking creativity, chose Case in point: I want to write (in Lua, and probably gambiarra at that, rather than |
Wow your test plans are taking shape. As I see it the plan with the teo ESPs is that they are only needed for extended perifery testing. I would like to also use them for tcp testing. One being the testee and one being the known-to-work counterpart which is also steered by the test running on the first ESP. But back to the naming issue: If this folder is to be populated by other test files it does not make sense to name it "lua" something of course. |
|
I think it would be better to have expect only orchestrate the test runs and execute the tests themselves as a Lua script on the ESP. That way everyone wanting to run a test could just do that without having to set up expect at all. |
I really, truly appreciate your point. I think the vast majority of testing can happen on device, which is why I wrote https://github.com/nwf/nodemcu-firmware/blob/dev-active/tests/tap-driver.expect and https://github.com/nwf/nodemcu-firmware/blob/dev-active/tests/shim_gambiarra.lua and nwf@28fd42e . Things like But certain things (esp., the trickier modules, which are all I've written tests for, because the easy ones are easy and I know how they will work, once I know what test harness we'd like to use) like |
Well, perhaps rather than all those words, an example is in order. Here, https://github.com/nwf/nodemcu-firmware/blob/dev-active/tests/test-adc.lua, is a test of the
If the LFS also contains I'm worried that |
The test looks very nice. Especially the generation of testcases. Maybe we could add data driven tests here, Just giving an array of params and then integrate the loop into gambiarra. But for the But it should be no problem instrumenting gambiarra with that. It supports async tests allready. About the coroutines: test('timer real async', function(next)
local t = tmr.create();
t:alarm(500, tmr.ALARM_SINGLE, function()
ok(true, "async end")
next()
end)
ok(true, "sync ende")
end, true) would change to something like this: test('timer real async', function(CallbackFactory, await)
local t = tmr.create();
t:alarm(500, tmr.ALARM_SINGLE, CallbackFactory.timeout)
ok(true, "sync ende")
cbName, param1 = await()
ok(eq("timeout", cbName))
-- param1 is the timer which has been passed to the callback
ok(true, "async end")
end, true) So especially for simpler tests this seems easier to code to me. for fans of the next methode to be called to indicate the end of the test this can be used: test('timer real async', function(CallbackFactory, await)
next = CallbackFactory.next
local t = tmr.create();
t:alarm(500, tmr.ALARM_SINGLE, function()
ok(true, "async end")
next()
end)
ok(true, "sync ende")
await()
end, true) The while test runs in a coroutine and the await switches contect and waits for any callback issued by the factory and the returns wizth the first param as the callback name and the others the parameters passed to the cb. |
I think I misunderstand the gambiarra interface; is the intent to call Your examples seem like they have a good bit of boilerplate that's required for the async/callback machinery to operate; could we somehow more directly encapsulate that inside gambiarra? Say, by making |
The idea is to make repeated calls to test. I think it would be a good idea to start each test with a post but it would break async testing when a callback could happen on every Also a failing |
I'm concerned that the async tests that call |
Hm. Mixing async and sync tests seems more subtle than I'd want. I am trying to test
and that works if it's the end of the file, but if I replace the
then that one runs as soon as ETA: My default response to this would be to avoid on-device testing of anything asynchronous and just go hide behind the big hammers I know well (that is, |
Good to see, that you are having a look at this. I also stumbled across the fact, that the gambiarra_test file contains async tests only at the end but didn't have a closer look yet.
I am currently fixing some other stuff and changing the ok and nok tests to abort the test instead of continuing it. After that I will add starting the tests with a post rather than directly. So everything will be asynchronous in the end. Currently I am having problems if a test tails in a callback with a Lua error. They just reboot instead of failing the test. But maybe I can catch those with the new errorhandler which Terry iplemented. Will have to think about that next. |
Added support for sync test after async and evicting old tests from callstack. local test = require('gambiarra')
local marker = 0
test('set marker async', function(next)
local t = tmr.create();
t:alarm(500, tmr.ALARM_SINGLE, function()
marker = "marked"
ok(true, 'async bar')
next()
end)
ok(true, 'foo')
end, true)
test('check marker sync', function()
ok(eq(marker, "marked"), "marker check")
end)
test('check marker async', function(next)
ok(eq(marker, "marked"), "marker check")
next()
end, true) |
Added catching erros and failed tests in callbacks also. Next will be the integration of coroutines to run async tests as explained in #2984 (comment) I have it running but need to integrate it in gambiarra. Or should it stay separated? |
@nwf I would like to change the interface of gambiarra to allow for separate methods for e.g. setting the output handler and also add the ability to define after-test cleanup routines and before-test prepare routines. the interface would then be somethink like this: - local test = require('gambiarra')
+ local gambiarra = require('gambiarra')
+ local test = gambiarra.test
+ gambiarra.test("name", fn)
+ gambiarra.asynctest("name", fn)
+ gambiarra.cotest("name", fn) -- the yet to come tests, that run in coroutines
function report(e, test, msg, errormsg)
if e == 'begin' then
...
end
-- setting the report function, replacing the default one
- test(report)
+ gambiarra.report= report
gambiarra.cleanup = function() ... end
gambiarra.prepare = function() ... end cleanup and prepare can be set as often as needed and will be valid for all tests thereafter. |
That seems like a quite reasonable API. A few thoughts: Any reason not to run every test through Given the "parse entire file into one chunk" nature of Lua's Nit: I'd prefer |
3ed9566
to
c6c979b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One extremely minor thing I noticed while reading through. If you like it as it is, I'm content to leave well enough alone.
Once again I have to thank you for all your hard work on this; NTest looks really nice.
Is this ready to (squash) merge? |
From my point of view it is ready. I'v got more ideas but that's for a later PR. First we should get some experience with this. |
* Create mispec_file.lua * Initial commit of gambiarra * Adapt gambiarra to NodeMCU * adapt to NodeMCU spacing and add nok functionality * Some refactoring to make it easier to add new functionality * Add methode `fail` to check failing code and pass error messages to output - fail can be called with a function that should fail and a string which should be contained in the errormessage. - Pass failed check reasons to output. * Create gambiarra_file.lua * Add reporting of tests that failed with Lua error * ok, nok and fail will terminate the running test * Add capability to run sync and async tests in mixed order and have a task.post inbetween them * fix gambiarra self test to also run on device (not only host) Use less ram in checking tests directly after they ran. Use nateie task.post to tame watchdog. * Update file tests + add async tmr tests * Another fix in executing async test * Catch errors in callbacks using node.setonerror * change interface to return an object with several test methods * Update README.md * Change interface of Gambiarra + add reason for failed eq * Update gambiarra documentation * Add coroutine testcases to gambiarra * Delete mispec_file.lua as it is superseeded by gambiarra_file.lua * improve regexp for stack frame extraction * Use Lua 53 debug capabilities * move actual tests upfront * remove debug code + optimization * Show errors immediately instead of at the end of the test, freeing memory earlier * Split tests to be run in 2 tranches * rename to NTest and move to new location * Add tests to checking mechanisms * Add luacheck to tests * Some pushing around of files * more (last) fixes and file juggling * Minor tweaks and forgotten checkin * Add NTest selftest to travis * Trying how to master travis * another try * restrict NTest selftest to linux
The |
|
||
This Library is for NodeMCU versions Lua 5.1 and Lua 5.3. | ||
|
||
It is based on https://bitbucket.org/zserge/gambiarra and includes bugfixes, substantial extensions of functionality and adaptions to NodeMCU requirements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a dead end. Maybe link to https://github.com/imolein/gambiarra instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The source you give is also based on zserges gambiarra. zserge seems to have removed the repo, so I would just link to his account https://bitbucket.org/zserge
But the repo you give has a much better readme, so we might copy some from there.
The 'plan' was to convert them to NTest but as #3158 is on the way I was hoping that it would be fixed therein. |
What is unclear to me is how to actually run the tests -- are there step-by-step instructions somewhere? |
So far as I know there are no step-by-step instructions. Eventually, I hope the answer to be a shell script on the host controlling the DUTs, and I have such a thing, more or less, somewhere between my desk and my |
helps fixing #2145
dev
branch rather than formaster
.this has evolved, so I changed this description too:
Add test framework which can run tests like the following on an ESP
Also includes first tests for the file and tmr module, mainly to have a working example.