Skip to content
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

Fully isolate tests #4

Open
2ndBillingCycle opened this issue Aug 8, 2020 · 0 comments
Open

Fully isolate tests #4

2ndBillingCycle opened this issue Aug 8, 2020 · 0 comments

Comments

@2ndBillingCycle
Copy link
Owner

Currently, functions under test can affect state outside of their sandbox by requiring a module or package be accessible, and modifying that module.

For example:

package.preload.mod = function (...)
  return {
    a = 1,
    modify_a = function (self) self.a = self.a + 1 end,
  }
end

local function under_test()
  local mod = require "mod"
  mod:modify_a()
end

local env = {
  require = require,
  mod = require "mod"
}
setfenv(under_test, env)
local mod = require "mod"
print("a before test: "..tostring(mod.a))
under_test()
print("a after test:  "..tostring(mod.a))

This could be solved a variety of ways:

  • Find a way to make perfect, deep copies of modules that allow for their state to be modified
  • Write modules so that they don't need to modify the state of other modules

The first one is a pipe dream, since making deep copies of tables is a known serialization challenge in Lua, and would be difficult to do in pure Lua.

The second sounds more achievable, but currently the emit module allows recording the output, so modules like that wouldn't be able to be easily tested.

I think I'll have to settle for less than 100% test coverage, having to write modules to make them easier to test, and relying less on module state and more on function closures.

Also, currently, if amalg wraps modules up in the same way they currently are (i.e. with a function in the package.preload table), then the module can be cleared from package.loaded and re-required to "reset" it.

I don't think it would be a good idea to implement this, though, as it wouldn't really give any guarantees about preventing state manipulation.

I think when it's necessary, luassert's built in table copying should be where I look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant