-
Notifications
You must be signed in to change notification settings - Fork 19
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
Testing framework #3
Comments
As mentioned in #5, I hope that with the data driven approach, we can provide an official test runner (or test harness) but also allow 3rd-party more sophisticated test runners to run exactly the same test suite without modifications. The test cases themselves should be test framework agnostic and stay very clean and self-contained. This also has the advantage that there is no way that a Lua test framework library itself can affect the behaviors of the test cases in any way if we wish. |
@agentzh I've made a proof-of-concept test runner in the spirit of TestML and following the guidelines by @MikePall in his comment to issue #5. I've adapted some tests as an example (in the directories test/libs and test/libs_ext). Like ldoc it considers the The tags allow you to select or exclude certain tests, this allows for 'tiers' (slow/fast/lua52 etc.). It also considers the code before the first It's here: https://github.com/ladc/LuaJIT-test-cleanup
or
Let me know what you think. It still has a lot of TODOs of course, like the filenames used to extract failing code snippets to (currently uses os.tmpname()), etc. |
It seems kind of fragile trying to parse out the bodys of the test and append what you hope the helper functions are instead of just rewriting all the individual tests in a file into functions that you can just selectively call |
@fsfod Thank you for your feedback. I tried to find a solution that's minimally invasive to the tests, while avoiding the need to include a YAML parser or the like, and while allowing the tests to be run as-is. Of course a declarative framework like this would need a minimal specification for the tests' format, which would include that the chunk before the first |
I wonder why lua itself could not be the test format? Why rely on something else, when lua is perfectly capable of doing the job? Sent from my Windows Phone From: Lesley De Cruzmailto:notifications@github.com @fsfod Thank you for your feedback. I tried to find a solution that's minimally invasive to the tests, while avoiding the need to include a YAML parser or the like, and while allowing the tests to be run as-is. Of course a declarative framework like this would need a minimal specification for the tests' format, which would include that the chunk before the first Reply to this email directly or view it on GitHub: |
@Wiladams That would require more invasive changes to the tests, and no longer make them runnable as-is. Or it would require putting every (sub)test into a different file, which is not ideal either. |
Coming up with names for all the subtests seems a bit difficult if they were to be split into files but I guess you could just name them table/insert1.lua table/insert2.lua etc instead. I think parsing a test for subtests is fine. I would match subtests by balanced I don't know how important it is to not have dependencies but if you're going to use a stable version of luajit to run the tests you could just use ffi to iterate directories instead of relying on lfs. But that's something that should probably be looked at later. |
OK, the It's indeed better to drop the dependency on lfs in favour of an ffi solution (see ljsyscall and TINN). |
I wrote
OTOH if you're not testing a stable LuaJIT (or if you're in the process of porting it) you may appreciate a test runner that works in vanilla Lua... |
Or minilua Sent from my Windows Phone From: Lesley De Cruzmailto:notifications@github.com I wrote
OTOH if you're not testing a stable LuaJIT (or if you're in the process of porting it) you may appreciate a test runner that works in vanilla Lua... Reply to this email directly or view it on GitHub: |
@Wiladams I also considered minilua. But keep in mind that minilua lacks some core libraries and functions. If I understand correctly from
|
@ladc instead of trying to come up with a parser that matches --#header foo {
local ffi = require("ffi")
local bit = require("bit")
dofile("../common/ffi_util.inc")
ffi.cdef([[
typedef struct { int a,b,c; } foo1_t;
typedef int foo2_t[?];
void *malloc(size_t size);
void free(void *ptr);
]])
--#}
do
--#subtest test {
--#include foo
assert(ffi.sizeof("foo1_t") == 12)
local cd = ffi.new("foo1_t")
assert(ffi.sizeof(cd) == 12)
local foo1_t = ffi.typeof("foo1_t")
assert(ffi.sizeof(foo1_t) == 12)
cd = foo1_t()
assert(ffi.sizeof(cd) == 12)
--#}
end
do --#subtest test2 {
--#include foo
assert(ffi.sizeof("foo2_t", 3) == 12)
local cd = ffi.new("foo2_t", 3)
assert(ffi.sizeof(cd) == 12)
local foo2_t = ffi.typeof("foo2_t")
fails(ffi.sizeof, foo2_t)
assert(ffi.sizeof(foo2_t, 3) == 12)
cd = foo2_t(3)
assert(ffi.sizeof(cd) == 12)
--#}
end
do --#subtest test2 {
--#include foo
local tpi = ffi.typeof("int")
local tpb = ffi.typeof("uint8_t")
local t = {}
for i=1,200 do t[i] = tpi end
t[100] = tpb
local x = 0
for i=1,200 do x = x + tonumber(ffi.new(t[i], 257)) end
assert(x == 199*257 + 1)
--#}
end I think the prefix symbol makes it clear that this is something more than a comment. Instead of making a pseudo language you could use lua itself somehow too which at that point it becomes a generic macro thing. (--#header = [[ ... --#]] ... --#test1 = [[ ... --#include(header) ... --#]]) but I'm not sure if there's going to be much benefit or if it'll make things easier. |
Here's an example of what I'm thinking. Just deal with the test file as if it were a database of individual test cases. This is all pure lua, so a lua parser can deal with it. And if you want to split thing out, you can easily do that by just querying the table, and only running what you want. The added benefit is that you get more meta data associated with tests. So, if you want to run tests that are related to a particular area, you can easily do that. I just want to separate the difference between data, and the mechanism to run the tests. The data itself can easily be represented in lua itself, minimizing the need to create a different 'language' simply to represent the data. local testCases = {
}, {
} if not os.getenv("SLOWTEST") then return end -- Run all the test cases for tcase in ipairs(testCases) do for idx, tcase in ipairs(tcase) do
end end =============================== - Shaping clay is easier than digging it out of the ground. Date: Sat, 27 Feb 2016 06:08:52 -0800 @ladc instead of trying to come up with a parser that matches do end you do something like --#header foo { dofile("../common/ffi_util.inc") ffi.cdef([[ do do --#subtest test2 { do --#subtest test2 { I think the prefix symbol makes it clear that this is something more than a comment. Instead of making a pseudo language you could use lua itself somehow too which at that point it becomes a generic macro thing. (--#header = [[ ... --#]] ... --#test1 = [[ ... --#include(header) ... --#]]) but I'm not sure if there's going to be much benefit or if it'll make things easier. — |
That's probably how I would do it personally too but if it's important (for some reason?) to keep the tests as is in single lua files then I would do what I said. |
@Wiladams That's a lot of boilerplate. If you need additional metadata that can easily be parsed from the comments or tags. You could use a simple I really don't see the need to add a lot of overhead to the tests. I think it's best to keep the tests clean and simple and to not end up with thousands of files (seriously, this can be very painful on some systems). Please look at the example below: The tests remain very readable and immediately runnable, while you still have a lot of flexibility, like adding metadata using the tags and possibly arbitrary attributes. I'm also not sure if this 'fragility' is much of a concern? The files will be "cut" at The responsibility of not unintendedly leaking variables between the tests is with the writer of the tests, as is already the case. This will require some curation but this will be the case with any framework, and luacheck can certainly help there. |
@Wiladams I've implemented your suggestion to allow for more metadata, using the Please read the requirements by @MikePall again; I think I've addressed many of them in the proposed implementation. Missing features include documentation of the current features, parallellization, shuffling of tests, timing the runs to look for potential performance regressions, running a test multiple times. And C(-API) test are not handled yet. |
I didn't quite get the comment on "a lot of boilerplate". None of those attributes are required. If you leave them out, then what you have is essentially the same thing as what you're proposing, but, instead of using a special notation in the comments, I just use the language itself to indicate what's what. Saves me from having to require that special parser to separate out the meaning from the comments. I can just use plain old lua. Also, as far as the MikePall 'requirements', I take that as Mike's strong suggestions. He's not here to drive the effort, and he's said as much. He's leaving it in our hands. I thought I was following those strong suggestions. minimal dependencies, tests can stand on their own, executed from plain a normal lua... But, really, we should just go ahead and implement some things. We risk debating/prototyping ourselves into inaction. Not a single checkin since the original one... |
Rewriting the tests as Lua strings in a table would add unnecessary, repeated code, which to me is boilerplate. But a more important down side to me is that you lose a lot with this approach: syntax highlighting and other editor tools like luacheck or lua inspect don't work on the code inside the strings; the test files will compile even with syntax errors in the tests; you can't run the tests as-is. To be honest, I really don't look forward to refactoring the tests in this format. The parser is not that special, it basically just matches three leading dashes and parses the comments for tags and attributes. It doesn't get much simpler than that. It's implemented in #6. The resulting table is basically the one you would define explicitly in your proposed format. Anyway, the required test format can still be modified by replacing the parse() function in the module
The command line tool's output to stdout is currently quite crude and the features are not complete. But if you think it could useful (test format aside), please consider merging my pull request #6. |
I think you should just do a pull request and we can move from debate to reality. I'm not married to my idea as much as I was just demonstrating a concept. Sent from my Windows Phone From: Lesley De Cruzmailto:notifications@github.com Rewriting the tests as Lua strings in a table would add unnecessary, repeated code, which to me is boilerplate. But a more important down side to me is that you lose a lot with this approach: syntax highlighting and other editor tools like luacheck or lua inspect don't work on the code inside the strings; the test files will compile even with syntax errors in the tests; you can't run the tests as-is. To be honest, I really don't look forward to refactoring the tests in this format. The parser is not that special, it basically just matches three leading dashes and parses the comments for tags and attributes. It doesn't get much simpler than that. It's implemented in #6. The resulting table is basically the one you would define explicitly in your proposed format. Anyway, the required test format can still be modified by replacing the parse() function in the module
The command line tool's output to stdout is currently quite crude and the features are not complete. But if you think it could useful (test format aside), please consider merging my pull request #6. Reply to this email directly or view it on GitHub: |
Well, the code has already been written and the pull request has been sitting here for a week... See #6. |
I don't mind metadata that can be ignored but I still prefer wrap all the individual tests that are in a file in functions and use telescope to run them with optionally using your metadata to control what tests run and using it to declared special things to check like loops were JIT'ed instead of what I currently do. Maybe because I started with a different test setup to MikePaul but extracting failing test doesn't seem that useful to me based on my experience implementing intrinsic support for LuaJIT. I would just set a telescope test filter to only run failed tests I wanted based on the test name from the test declaration it("test name", function() end). I also ended up sticking what would be you tags in the test name as well |
@ladc, just to be complete: This can also work. You don't need to put the test code into a literal string, it can be bracketed by anything that can show up discretely in a table. At this point, eliminating the meta data, and turning the curly braces into '---', we have exactly the same thing, except mine is parseable by lua directly, not requiring any sort of test parser. |
Using Lua for the test spec is very bad since it makes alternative test scaffolds written in other languages (like Perl and Python) much much harder. We need the capability to run the same test suite in various wildly different ways. BTW, TestML supports custom section delimiters other than http://testml.org/specification/language//index.html I believe it's very wrong and limited to assume the test scaffold is always Lua. |
I'm not sure you're reading my comments correctly. and: { annotation = "here" In either case, you can still have a test runner in PHP or whatever language you choose. It just so happens that the annotations I'm selection are parseable using Lua as well. The real question to me is "can we choose a test case format that is easily parseable by lua as well as other languages?" Is it necessary to make it harder for Lua to be the test case parser? At any rate, I'm not pushing for anything here because I don't think it's worth the argument. The thing that should be selected is the thing we have tools for. It will no doubt change over time anyway. |
Whichever representation we choose right now, it'll be trivial to parse and reformat the tests in the format which we ultimately decide to go for. |
I agree. Its more important to get some momentum at the moment. Sent from my Windows Phone -----Original Message----- Whichever representation we choose right now, it'll be trivial to parse and reformat the tests in the format which we ultimately decide to go for. |
Help! I really need a simple way to drive the tests for the CI in #10. The ideal would be:
Could any kind soul provide this? The current solution is basically to enumerate the tests with The drop-in solution would be to refactor I am happy to take care of the CI side if somebody can support on the test suite side :). |
Agree on a testing library and a test runner with minimal dependencies, preferably Lua/shell only.
Test cases should still be easy to run without any (big) dependencies.
The text was updated successfully, but these errors were encountered: