describe and it Blocks
Structure a test suite.
describe and it Blocks is a free Lua Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Structure of a Spec
busted organizes tests with two core functions: describe and it. A describe block groups related tests, and each it block is a single test case.
This structure comes from behavior driven development and reads like plain English.
describe("Stack", function()
it("starts empty", function()
assert.are.equal(0, Stack.new():size())
end)
end)The describe Block
describe takes a name string and a function. The name should identify the unit or feature being tested, such as a module or class.
Everything inside the function belongs to that group. The name appears in the test output to organize results.
describe("calculator", function()
-- tests live here
end)The it Block
Each it block describes one specific behavior. The string should complete the sentence started by describe.
Read together, "calculator" plus "adds two numbers" forms a clear specification of intent.
describe("calculator", function()
it("adds two numbers", function()
assert.are.equal(5, calc.add(2, 3))
end)
end)Nesting describe Blocks
You can nest describe blocks to express context. An inner block might describe a specific method or a special condition.
Nesting keeps related cases together and produces readable, indented output.
describe("List", function()
describe("push", function()
it("adds an item", function()
assert.are.equal(1, list:push("a"):size())
end)
end)
end)before_each Setup
before_each runs a function before every it in its block. Use it to build fresh test data so tests do not share state.
This keeps each test isolated. A change in one test cannot leak into the next.
describe("Stack", function()
local s
before_each(function()
s = Stack.new()
end)
it("pushes", function()
s:push(1)
assert.are.equal(1, s:size())
end)
end)after_each Teardown
after_each runs after every test. Use it to clean up resources such as temporary files, open connections, or global state.
Pairing setup and teardown ensures the environment is reset between tests.
after_each(function()
os.remove("temp.db")
end)setup and teardown
busted also offers setup and teardown, which run once per describe block rather than once per test.
Use these for expensive one time work, like opening a shared connection, when per test setup would be wasteful.
describe("db", function()
setup(function()
db = connect()
end)
teardown(function()
db:close()
end)
end)Pending Tests
Sometimes you want to note a test you have not written yet. Call pending with a description, or write an it block with no function.
busted reports these as pending rather than passing or failing, reminding you to finish them.
it("handles unicode", function()
pending("not implemented yet")
end)Focusing and Excluding
While debugging you can focus on a subset of tests. Tagging with --tags on the command line, or using busted helpers, lets you run only what matters.
This avoids running the whole suite while you iterate on one failing area.
-- run only tests tagged 'fast'
-- busted --tags=fastNaming Conventions
Good names make failures self explanatory. Start describe with the subject and start it with a verb describing behavior.
Avoid vague names like "works" or "test1". A failing test should read like a bug report you can act on.
describe("parser", function()
it("rejects malformed input", function()
assert.has_error(function() parser.parse("{") end)
end)
end)Putting It Together
A complete spec combines describe groups, before_each setup, and focused it cases. This skeleton scales from one test to hundreds.
Keep blocks small and each it focused on a single behavior for the clearest output.
describe("Account", function()
local acc
before_each(function() acc = Account.new(100) end)
it("withdraws funds", function()
acc:withdraw(40)
assert.are.equal(60, acc.balance)
end)
end)Quick Check
Test your understanding of busted block structure.
Recap
describe groups related tests and it defines a single case, reading like a specification. Nest describe blocks to express context.
Use before_each and after_each for per test isolation, and setup and teardown for once per block work. Mark unfinished work with pending.
Frequently asked questions
Is the “describe and it Blocks” lesson free?
Yes — the full text of “describe and it Blocks” is free to read here on the web, and the Lua Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Lua Academy course, upgrade to CoddyKit PRO.
What will I learn in “describe and it Blocks”?
Structure a test suite. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Lua Academy?
No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “describe and it Blocks” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Lua Academy lesson?
Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Why Test
- describe and it Blocks
- Assertions
- Mocks and Spies