Automatic Unit Testing - Italian translation added
This commit is contained in:
parent
1df1473ea7
commit
f97afc2f99
@ -1,61 +1,59 @@
|
||||
---
|
||||
title: Automatic Unit Testing
|
||||
title: Testing d'unità automatici
|
||||
layout: default
|
||||
root: ../..
|
||||
idx: 8.5
|
||||
---
|
||||
|
||||
## Introduction <!-- omit in toc -->
|
||||
## Introduzione <!-- omit in toc -->
|
||||
|
||||
Unit tests are an essential tool in proving and reassuring yourself that your code
|
||||
is correct. This chapter will show you how to write tests for Minetest mods and
|
||||
games using Busted. Writing unit tests for functions where you call Minetest
|
||||
functions is quite difficult, but luckily [in the previous chapter](clean_arch.html),
|
||||
we discussed how to structure your code avoid this.
|
||||
I testing d'unità sono uno strumento essenziale nell'assicurarsi che il codice sia corretto.
|
||||
Questo capitolo ti mostrerà come scrivere questi per le mod e i giochi di Minetest usando Busted.
|
||||
Scrivere i testing d'unità per le funzioni dove vengono chiamate quelle di Minetest è alquanto difficile, ma per fortuna abbiamo già discusso [nel capitolo precedente](clean_arch.html) come strutturare il codice in modo da non complicarci la vita.
|
||||
|
||||
- [Installing Busted](#installing-busted)
|
||||
- [Your First Test](#your-first-test)
|
||||
- [Installare Busted](#installare-busted)
|
||||
- [Il tuo primo test](#il-tuo-primo-test)
|
||||
- [init.lua](#initlua)
|
||||
- [api.lua](#apilua)
|
||||
- [tests/api_spec.lua](#testsapispeclua)
|
||||
- [Mocking: Using External Functions](#mocking-using-external-functions)
|
||||
- [Checking Commits with Travis](#checking-commits-with-travis)
|
||||
- [Conclusion](#conclusion)
|
||||
- [Simulare: usare funzioni esterne](#simulare-usare-funzioni-esterne)
|
||||
- [Controllare commit con Travis](#controllare-commit-con-travis)
|
||||
- [Conclusione](#conclusione)
|
||||
|
||||
## Installing Busted
|
||||
## Installare Busted
|
||||
|
||||
First, you'll need to install LuaRocks.
|
||||
Prima di tutto, c'è bisogno di installare LuaRocks.
|
||||
|
||||
* Windows: Follow the [installation instructions on LuaRock's wiki](https://github.com/luarocks/luarocks/wiki/Installation-instructions-for-Windows).
|
||||
* Windows: segui le istruzioni sulla [wiki di LuaRocks](https://github.com/luarocks/luarocks/wiki/Installation-instructions-for-Windows).
|
||||
* Debian/Ubuntu Linux: `sudo apt install luarocks`
|
||||
|
||||
Next, you should install Busted globally:
|
||||
Poi, dovresti installare Busted a livello globale:
|
||||
|
||||
sudo luarocks install busted
|
||||
|
||||
Finally, check that it is installed:
|
||||
Infine, controlla che sia installato:
|
||||
|
||||
busted --version
|
||||
|
||||
|
||||
## Your First Test
|
||||
## Il tuo primo test
|
||||
|
||||
Busted is Lua's leading unit test framework. Busted looks for Lua files with
|
||||
names ending in `_spec`, and then executes them in a standalone Lua environment.
|
||||
Busted è il quadro strutturale (o *framework*) per eccellenza di Lua.
|
||||
Quello che fa è cercare i file Lua con il nome che termina in `_spec`, eseguendoli poi in un ambiente Lua a sé stante.
|
||||
|
||||
mymod/
|
||||
miamod/
|
||||
├── init.lua
|
||||
├── api.lua
|
||||
└── tests
|
||||
└── test
|
||||
└── api_spec.lua
|
||||
|
||||
|
||||
### init.lua
|
||||
|
||||
```lua
|
||||
mymod = {}
|
||||
miamod = {}
|
||||
|
||||
dofile(minetest.get_modpath("mymod") .. "/api.lua")
|
||||
dofile(minetest.get_modpath("miamod") .. "/api.lua")
|
||||
```
|
||||
|
||||
|
||||
@ -63,7 +61,7 @@ dofile(minetest.get_modpath("mymod") .. "/api.lua")
|
||||
### api.lua
|
||||
|
||||
```lua
|
||||
function mymod.add(x, y)
|
||||
function miamod.somma(x, y)
|
||||
return x + y
|
||||
end
|
||||
```
|
||||
@ -71,103 +69,94 @@ end
|
||||
### tests/api_spec.lua
|
||||
|
||||
```lua
|
||||
-- Look for required things in
|
||||
package.path = "../?.lua;" .. package.path
|
||||
-- Cerca le cose necessarie in package.path = "../?.lua;" .. package.path
|
||||
|
||||
-- Set mymod global for API to write into
|
||||
-- Imposta la globale miamod per far sì che l'API possa scriverci sopra
|
||||
_G.mymod = {} --_
|
||||
-- Run api.lua file
|
||||
-- Esegue il file api.lua
|
||||
require("api")
|
||||
|
||||
-- Tests
|
||||
describe("add", function()
|
||||
it("adds", function()
|
||||
assert.equals(2, mymod.add(1, 1))
|
||||
-- Test vari
|
||||
describe("somma", function()
|
||||
it("aggiunge", function()
|
||||
assert.equals(2, miamod.somma(1, 1))
|
||||
end)
|
||||
|
||||
it("supports negatives", function()
|
||||
assert.equals(0, mymod.add(-1, 1))
|
||||
assert.equals(-2, mymod.add(-1, -1))
|
||||
it("supporta valori negativi", function()
|
||||
assert.equals(0, miamod.somma(-1, 1))
|
||||
assert.equals(-2, miamod.somma(-1, -1))
|
||||
end)
|
||||
end)
|
||||
```
|
||||
|
||||
You can now run the tests by opening a terminal in the mod's directory and
|
||||
running `busted .`
|
||||
Puoi ora eseguire i vari test aprendo un terminale nella cartella della mod ed eseguendo `busted .`.
|
||||
|
||||
It's important that the API file doesn't create the table itself, as globals in
|
||||
Busted work differently. Any variable which would be global in Minetest is instead
|
||||
a file local in busted. This would have been a better way for Minetest to do things,
|
||||
but it's too late for that now.
|
||||
È importante che il file dell'API non crei da sé la tabella, in quanto le variabili globali su Busted funzionano diversamente.
|
||||
Ogni variabile che dovrebbe essere globale su Minetest è invece un file locale su Busted.
|
||||
Sarebbe stato un modo migliore per Minetest di gestire le cose, ma è ormai troppo tardi per renderlo realtà.
|
||||
|
||||
Another thing to note is that any files you're testing should avoid calls to any
|
||||
functions not inside of it. You tend to only write tests for a single file at once.
|
||||
Un'altra cosa da notare è che qualsiasi file si stia testando, bisognerebbe evitare che chiami funzioni al di fuori di esso.
|
||||
Si tende infatti a scrivere i test che controllino un solo file alla volta.
|
||||
|
||||
|
||||
## Mocking: Using External Functions
|
||||
## Simulare: usare funzioni esterne
|
||||
|
||||
Mocking is the practice of replacing functions that the thing you're testing depends
|
||||
on. This can have two purposes; one, the function may not be available in the
|
||||
test environment, and two, you may want to capture calls to the function and any
|
||||
passed arguments.
|
||||
Il simulare (*mocking*) è la pratica di sostituire le funzioni dalle quali la parte di codice da testare è dipendente.
|
||||
Questo può avere due obiettivi: il primo, la funzione potrebbe non essere disponibile nell'area di testing; il secondo, si potrebbero voler catturare le chiamate alla funzione e gli argomenti da essa passati.
|
||||
|
||||
If you follow the advice in the [Clean Architectures](clean_arch.html) chapter,
|
||||
you'll already have a pretty clean file to test. You will still have to mock
|
||||
things not in your area, however - for example, you'll have to mock the view when
|
||||
testing the controller/API. If you didn't follow the advice, then things are a
|
||||
little harder as you may have to mock the Minetest API.
|
||||
Se si sono seguiti i consigli nel capitolo delle [Architetture pulite](clean_arch.html), si avrà già un file bello pronto da testare, anche se si dovrà comunque simulare le cose non contenute nell'area di testing (per esempio, la vista quando si testa il controllo/API).
|
||||
Se invece si è deciso di lasciar perdere quella parte, allora le cose sono un po' più complicate in quanto ci sarà da simulare anche la API di Minetest.
|
||||
|
||||
```lua
|
||||
-- As above, make a table
|
||||
-- come prima, crea una tabella
|
||||
_G.minetest = {}
|
||||
|
||||
-- Define the mock function
|
||||
local chat_send_all_calls = {}
|
||||
-- Definisce la funzione simulata
|
||||
local chiamate_chat_send_all = {}
|
||||
function minetest.chat_send_all(name, message)
|
||||
table.insert(chat_send_all_calls, { name = name, message = message })
|
||||
table.insert(chiamate_chat_send_all, { nome = name, messaggio = message })
|
||||
end
|
||||
|
||||
-- Tests
|
||||
describe("list_areas", function()
|
||||
it("returns a line for each area", function()
|
||||
chat_send_all_calls = {} -- reset table
|
||||
-- Test
|
||||
describe("elenca_aree", function()
|
||||
it("ritorna una riga per ogni area", function()
|
||||
chiamate_chat_send_all = {} -- resetta la tabella
|
||||
|
||||
mymod.list_areas_to_chat("singleplayer", "singleplayer")
|
||||
miamod.elenca_aree_chat("singleplayer", "singleplayer")
|
||||
|
||||
assert.equals(2, #chat_send_all_calls)
|
||||
assert.equals(2, #chiamate_chat_send_all)
|
||||
end)
|
||||
|
||||
it("sends to right player", function()
|
||||
chat_send_all_calls = {} -- reset table
|
||||
it("invia al giocatore giusto", function()
|
||||
chiamate_chat_send_all = {} -- resetta la tabella
|
||||
|
||||
mymod.list_areas_to_chat("singleplayer", "singleplayer")
|
||||
miamod.elenca_aree_chat("singleplayer", "singleplayer")
|
||||
|
||||
for _, call in pairs(chat_send_all_calls) do --_
|
||||
assert.equals("singleplayer", call.name)
|
||||
for _, chiamata in pairs(chiamate_chat_send_all) do --_
|
||||
assert.equals("singleplayer", chiamata.nome)
|
||||
end
|
||||
end)
|
||||
|
||||
-- The above two tests are actually pointless,
|
||||
-- as this one tests both things
|
||||
it("returns correct thing", function()
|
||||
chat_send_all_calls = {} -- reset table
|
||||
-- I due test qui in alto in verità sono inutili in quanto
|
||||
-- questo li esegue entrambi
|
||||
it("ritorna correttamente", function()
|
||||
chiamate_chat_send_all = {} -- resetta la tabella
|
||||
|
||||
mymod.list_areas_to_chat("singleplayer", "singleplayer")
|
||||
miamod.elenca_aree_chat("singleplayer", "singleplayer")
|
||||
|
||||
local expected = {
|
||||
{ name = "singleplayer", message = "Town Hall (2,43,63)" },
|
||||
{ name = "singleplayer", message = "Airport (43,45,63)" },
|
||||
local previsto = {
|
||||
{ nome = "singleplayer", messaggio = "Town Hall (2,43,63)" },
|
||||
{ nome = "singleplayer", messaggio = "Airport (43,45,63)" },
|
||||
}
|
||||
assert.same(expected, chat_send_all_calls)
|
||||
assert.same(previsto, chiamate_chat_send_all)
|
||||
end)
|
||||
end)
|
||||
```
|
||||
|
||||
|
||||
## Checking Commits with Travis
|
||||
## Controllare commit con Travis
|
||||
|
||||
The Travis script from the [Automatic Error Checking](luacheck.html)
|
||||
chapter can be modified to also run Busted.
|
||||
Lo script di Travis usato nel capitolo [Controllo automatico degli errori](luacheck.html) può essere modificato per eseguire (anche) Busted
|
||||
|
||||
```yml
|
||||
language: generic
|
||||
@ -186,10 +175,8 @@ notifications:
|
||||
```
|
||||
|
||||
|
||||
## Conclusion
|
||||
## Conclusione
|
||||
|
||||
Unit tests will greatly increase the quality and reliability of your project if used
|
||||
well, but they require you to structure your code in a different way than usual.
|
||||
I testing d'unità aumenteranno notevolmente la qualità e l'affidabilità di un progetto se usati adeguatamente, ma ti richiederanno di strutturare il codice in maniera diversa dal solito.
|
||||
|
||||
For an example of a mod with lots of unit tests, see
|
||||
[crafting by rubenwardy](https://github.com/rubenwardy/crafting).
|
||||
Per un esempio di mod con molti testing d'unità, vedere la [crafting di rubenwardy](https://github.com/rubenwardy/crafting).
|
||||
|
Loading…
Reference in New Issue
Block a user