Unit testing in Picotron. Make sure your code works as expected.
- download cart png from releases page and put it somewhere on Picotron drive (desktop for example)
- run the cart by double clicking
- create a Lua file with following test code:
assert_eq("hello", "hello")
- drag and drop the file to unitron window
- see examples folder for details how to write tests
Because you want to make sure that the functions you use in your game work as intended and do not cause errors that the player himself will notice. By observing the operation of the entire program, it is difficult to verify whether a function used somewhere at the bottom of your program actually works. Unit tests allow you to verify whether a function works as intended and how it deals with edge cases.
Over time, the code of your functions becomes more and more complex. Functions that were simple at the beginning start to look like spaghetti - whether it's due to subsequent if statements added or optimizations you introduced to make the game run at 60 fps. So you need to go back to that code every now and then and clean it up. However, making changes to existing code involves the risk of making mistakes. So you have to be very careful when making changes and then manually verifying them. However, if you have unit tests for this code, you just need to run these tests again after each change to the code. The tests are quick and will give you results in a fraction of a second. Manual testing would take much longer. Having unit tests actually encourages you to come back to your code often and improve it.
Only the code whose behavior changes very rarely. Behavior describes the effect of executing some code - for example, running the add
function on two numbers adds these numbers together and returns the result. What the result will be is predetermined - the arithmetic will never change here. Any reusable functions and objects that you currently use in multiple places in your games are potentially code that you can write unit tests against. They are so generic that they are unlikely to change very often. Moreover, over time, your game's code will become more and more stable - that is, it will not change significantly. Then you can extract functions and objects from it and write tests for them.
In my opinion, writing tests while prototyping a game makes no sense. The only exception is writing tests just for educational purposes :)
- Introduction
- test
- assert_eq
- assert_not_eq
- assert_close
- assert_not_close
- assert_nil
- assert_not_nil
- test_helper
- test_fail
Test API provides functions for writing your own tests. You don't have to include
any Lua files in your test files. Unitron automatically includes all the necessary files for you, when you drag and drop your file into unitron's window.
Tests can be slow. That's why unitron runs them in the background - in a separate process. Thanks to that unitron window is always responsive.
Tests can do whatever they want - they can use any function provided by Picotron. For example, they can draw on screen. The effect will not be visible, because tests are executed in a separate process.
When assertion inside test failed, the test is stopped immediately. Functions stop and no more code is executed from the test. If test had more assertions they are not executed. If test had more subtests they are not executed as well. Parent test is marked as failed, as well as parent of the parent (all way up to the root). On the other hand, parent's subtests are executed normally.
See examples for tutorial-like instructions how to write unit tests in unitron.
syntax: test(name_of_the_test, function() ... end)
Starts a test with a given name and code. Test code is inside anonymous function.
test("name of the test", function()
-- here goes the test code
end)
Tests are executed sequentially.
Tests can be nested. When nested test fails, the parent also fails.
syntax: assert_eq(expected, actual, message?)
Asserts that expected
and actual
are equal. Values must have the same type.
For strings, numbers and booleans ==
operator is used.
For tables, all keys and values are compared deeply.
If you want to check if two variables reference to the same table in memory
please use assert(a==b)
instead.
Tables could have cycles.
For userdata, all data is compared and userdata must be of the same type, width and height.
syntax: assert_not_eq(expected, actual, message?)
Asserts that expected
and actual
are not equal. The function has similar behavior to assert_eq.
syntax: assert_close(expected, actual, delta, message?)
Asserts that expected
number is close to actual
number. The maximum error is delta
.
syntax: assert_not_close(not_expected, actual, delta, message?)
Asserts that not_expected
number is not close to actual
number.
syntax: assert_nil(actual, message?)
Asserts that actual
is nil
.
syntax: assert_not_nil(actual, message?)
Asserts that actual
is not nil
.
syntax: test_helper()
test_helper
marks the calling function as a test helper function.
When printing file and line information in GUI, that function will be
skipped.
syntax: test_fail(err)
Generates test error which stops current test execution and shows error to
the user. In the GUI, the error will be presented together with a file name
and line number where the test_fail
function was executed. If you run
test_fail
from your own assert function, and want to see a place where this
assert function was executed instead, please run the test_helper() function in the beginning of your assert function:
function custom_assert(....)
test_helper() -- mark custom_assert function as test helper
if .... then
test_fail("message")
end
end
err
is an error message as a string or a table. All table fields will be presented in the GUI. Table could contain special msg
field which will always be presented first.
- clone repository to Picotron drive and name it unitron.src.p64
git clone https://github.com/elgopher/unitron unitron.src.p64
- edit the source code in editor of choice (such as VS Code with sumneko's Lua Language Server)
- to release cartridge
- go to Picotron terminal and type
cp unitron.src.p64 unitron.p64.png
- publish post on BBS
- go to Picotron terminal and type