testingautomationluaintegration-testingroblox

Is there a way to test roblox games?


As I started to understand a little bit more about Roblox, I was wondering if there is any possible way to automate the testing. As a first step only on the Lua scripting, but ideally also simulating the game and interactions.

Is there any way of doing such a thing? Also if there are already best practices on doing testing on Roblox(this includes Lua scripting) I would like to know more about them.


Solution

  • Unit Testing

    For lua modules, I would recommend the library TestEZ. It was developed in-house by Roblox engineers to allow for behavior driven tests. It allows you to specify a location where test files exist and will gives you pretty detailed output as to how your tests did.

    This example will run in RobloxStudio, but you can pair it with other libraries like Lemur for command-line and continuous integration workflows. Anyways, follow these steps :

    1. Get the TestEZ Library into Roblox Studio

    1. Download Rojo. This program allows you to convert project directories into .rbxm (Roblox model object) files.
    2. Download the TestEZ source code.
    3. Open a Powershell or Terminal window and navigate into the downloaded TestEZ directory.
    4. Build the TestEZ library with this command rojo build --output TestEZ.rbxm .
    5. Make sure that it generated a new file called TestEZ.rbxm in that directory.
    6. Open RobloxStudio to your place.
    7. Drag the newly created TestEZ.rbxm file into the world. It will unpack the library into a ModuleScript with the same name.
    8. Move this ModuleScript somewhere like ReplicatedStorage.

    2. Create unit tests

    In this step we need to create ModuleScripts with names ending in `.spec` and write tests for our source code.

    A common way to structure code is with your code classes in ModuleScripts and their tests right next to them. So let's say you have a simple utility class in a ModuleScript called MathUtil

    local MathUtil = {}
    
    function MathUtil.add(a, b)
        assert(type(a) == "number")
        assert(type(b) == "number")
        return a + b
    end
    
    return MathUtil
    

    To create tests for this file, create a ModuleScript next to it and call it MathUtil.spec. This naming convention is important, as it allows TestEZ to discover the tests.

    return function()
        local MathUtil = require(script.parent.MathUtil)
        
        describe("add", function()
            it("should verify input", function()
                expect(function()
                    local result = MathUtil.add("1", 2)
                end).to.throw()
            end)
            
            it("should properly add positive numbers", function()
                local result = MathUtil.add(1, 2)
                expect(result).to.equal(3)
            end)
            
            it("should properly add negative numbers", function()
                local result = MathUtil.add(-1, -2)
                expect(result).to.equal(-3)
            end)
        end)
    end
    

    For a full breakdown on writing tests with TestEZ, please take a look at the official documentation.

    3. Create a test runner

    In this step, we need to tell TestEZ where to find our tests. So create a Script in ServerScriptService with this :

    local TestEZ = require(game.ReplicatedStorage.TestEZ)
    
    -- add any other root directory folders here that might have tests 
    local testLocations = {
        game.ServerStorage,
    }
    local reporter = TestEZ.TextReporter
    --local reporter = TestEZ.TextReporterQuiet -- use this one if you only want to see failing tests
     
    TestEZ.TestBootstrap:run(testLocations, reporter)
    

    4. Run your tests

    Now we can run the game and check the Output window. We should see our tests output :
    Test results:
    [+] ServerStorage
       [+] MathUtil
          [+] add
             [+] should properly add negative numbers
             [+] should properly add positive numbers
             [+] should verify input
    3 passed, 0 failed, 0 skipped - TextReporter:87
    

    Automation Testing

    For automated tests, you can simply use TestEZ to script together interactions and verify that they happened. For example, you could write a test function that spawns an NPC, has it walk to a location, pick up a weapon, and tells them to fire a bullet at a target. You could write assertions and expectations that the NPC's character model has the gun in its model hierarchy, or that after a few seconds it arrives at the correct location, or that the target's health has changed.

    The only tricky part is that the test must resolve synchronously, so you'll need to get clever with spawn and wait to kick of async logic while yielding the test thread.