问题标签 [ex-unit]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
94 浏览

elixir - 为什么在 setup_all 块中插入数据库的对象没有出现在测试块中?

我在控制器中进行了类似的测试,并且setup_all测试块中提供了插件。在这里,我试图在我的模型中允许同样的事情,但我似乎无法让它发挥作用。

我有一个测试如下:

当我运行它时,出现以下错误:

现在在setup_all块中,我进行与在块中相同的验证test。为什么它会在测试中失败但通过setup_all

0 投票
1 回答
786 浏览

elixir - Elixir:在测试中重新定义模块

我有一个 ping 端点的 ExUnit 测试。该端点调用一个函数,该函数通过一个由环境确定的 http 客户端进行外部调用,例如 la Jose Valim 的著名帖子

在测试环境中,我使用的是 HTTPoison 的模拟模块。

在测试本身中,我试图重新定义这个模块,以便该函数返回一个预设响应。

但是,未使用重新定义的模块。运行测试时出现原始错误。

我也尝试使用模拟库来执行此操作,这会引发不同的错误,即使我直接模拟 HTTPoison 也是如此。

为什么没有使用我重新定义的模块?

0 投票
1 回答
298 浏览

elixir - 在 ExMachina 中测试/验证工厂变更集和可重复模式测试

这不是问题,我只是想确保这段代码对我认为的测试有效果。我想要一个通过工厂构建/创建结构的测试,并检查以确保变更集有效,就像默认生成的测试一样。这样,我的工厂也经过测试以生成有效数据。

例如,这个默认测试使用属性映射来创建结构变更集并验证数据:

可以这样用工厂重写吗?

当我在学习 Elixir 时,有时语义会令人困惑,我希望得到一些澄清,这是正确的方向。是否传递了一个空的属性映射,因为它们已经由验证变更集user的工厂函数定义?build(:user)

我的下一步将是像我在 Rails/Rspec/FactoryGirl 中所做的那样,我有一个 FactorySpec 来构建每个模型并验证模型是否正确构建。在此示例中,工厂规范构建每个模型并对其进行验证。

最后,关于如何在 ExUnit 中创建规范/测试,使用它们各自的工厂可重复测试所有结构以验证它们的生成,是否有任何建议build/create

我在ExMachina 存储库中打开了一个问题 (198)以供交叉参考。

0 投票
1 回答
274 浏览

recursion - 在 Elixir/Erlang 中测试递归 IO 提示

我有一个函数confirm,它读取 IO 输入,并根据输入,如果它是y(是)或n(否),它会返回true/false,否则它会confirm再次调用,直到输入任何预期的yn

测试yn案例很容易:

assert capture_io([input: "y"], fn -> confirm("Question") end) == "Question"

但是我不知道如何多次捕获 IO 来测试递归情况,假设第一次输入是“无效”然后是“y”。elixir 有没有办法测试这样的 IO 功能?或者你有什么建议我可以重写函数来更容易地测试它吗?

原始问题https://elixirforum.com/t/testing-recursive-io-prompt/3715

谢谢您的帮助。

0 投票
2 回答
423 浏览

database - 如何使用 Repo 刷新数据库

更具体地说,我有一个使用 Ecto 和 Repo 的 Phoenix 应用程序。我想在运行每个更改数据库的 Exunit 测试后刷新我的数据库。

我可以做到这一点的一种方法是change在目录中运行迁移中的所有功能priv/repo/migrations/,但我觉得应该有更好的方法。

也许像运行刷新功能一样?

0 投票
2 回答
3266 浏览

unit-testing - Elixir / ExUnit:将上下文从测试用例传递到拆卸/清理方法(on_exit)可能吗?

问题

我想测试一个与主机系统交互并且具有副作用的方法的 Elixir 模块。对于这个问题并保持简短,假设它是创建几个目录。这些目录当然应该在测试运行后删除,如果测试(很长)由于任何原因(错误的模块代码、错误的测试代码等)失败。

我想知道如何最好/最优雅地解决这个清理步骤。我查看了ExUnit.Callbacks.on_exit/2的文档,但它的示例仅用于设置和简单的拆卸(不涉及传递状态)。我也在网上搜索过,但没有发现任何有用的东西,所以可能是我的想法本身不好 - 我也愿意接受重新定义问题的建议。

例子

可能的解决方案?

我现在想cleanup/1在每次测试后添加一个要删除的目录列表的调用。以下想法是我尝试过的事情:

  • 在每个测试结束时直接调用该函数:适用于简单的情况,但如果测试用例无限循环,它将被杀死并且不再进行清理。
  • 在每个测试中使用更新的上下文进行调用on_exit(fn -> cleanup(context) end):这似乎可行,但我无法确定是否推荐它,以及在测试中放置调用的位置(开始/结束)是否有所不同。
  • 调用函数:文档执行on_exit(fn -> cleanup(context) end)setup context操作,但我不知道如何将任何新状态/上下文传递给它。只有在设置函数中已经完全定义了所有上下文时,它似乎才有用。

也许我也多虑了这个问题......我只是在不完整的清理和导致无休止的递归中遇到了一些糟糕的调试经验(这应该被我的代码捕获,但还没有),所以我只想确保我做到了正确的事情并以正确的方式学习。除了这些测试之外,到目前为止,Elixir 是一次非常愉快且完美的体验!

0 投票
1 回答
1267 浏览

unit-testing - Elixir/ExUnit:如何用系统调用最优雅地测试函数?

情况

通常,像 ExUnit 这样的单元测试应该是自包含的,包含输入、函数调用和所需的输出,以便测试可以在任何系统上运行,并且无论环境如何都能正确测试。

另一方面,如果您的应用程序执行系统调用,例如使用 ElixirSystem.cmd/3或 Erlang 的:os.cmd/1并使用结果,您的测试可能会因为不同/更新的二进制文件、更改的环境、不同的操作系统等原因而得到不同的结果。

当然,在这些情况下测试失败是好的,这样你对现实生活情况的覆盖范围就会增加。然而,在开发时,您会希望首先让您的函数做正确的事情,然后才能做正确的事情。如果外部世界发生变化,则很难甚至不可能始终以可预测的方式运行测试。

此外,您可能想要测试很少或几乎不会发生的情况,但是您的系统调用不会为您提供该信息,因为它确实很少发生。您需要以某种方式模拟系统调用的输出并将其与程序的内部逻辑分开。


例子

为了简单起见(同样的原则适用于更复杂的情况),请考虑读取系统的启动时间并根据清理后的结果进行响应:

只有在特定时间重新启动系统才能正确测试此功能,这当然是不合理的。但是由于输出的格式大致已知,您可以创建一个测试值列表,例如['16:04', '23:59', '12:00', "12:00", 2, "xyz", '1.0"]并在没有系统调用的情况下测试解析部分,然后像往常一样将其与您的预期结果进行比较。

天真的方法

但是这是怎么做到的呢?系统调用是函数中的第一件事,所以如果你把它放到一个单独的函数中,你可以测试系统调用,但这对你没有多大帮助,因为系统调用本身就是问题:

稍微好一些...

如果您添加另一个仅解析字符串/字符列表的辅助方法,您可以实现您想要的,同时将系统调用本身设为私有:

现在您可以在 ExUnit 案例中调用辅助测试函数,正常程序可以调用正常函数。

……但不好?

虽然最后一个想法在实践中有效,但我觉得它不是很优雅。我可以看到以下缺点:

  1. 每个函数都需要拆分为私有系统调用、公共助手和公共普通方法,函数数量增加了三倍。由于不必要的分区,生成的代码更长且更难阅读。
  2. 辅助方法需要公开才能进行测试,但不应向公众公开。因此,必须编写额外的文档,API 参考变得更长,并且该方法必须进行更多检查以确保安全操作(而以前,只有系统调用本身产生的值才会发生)。
  3. 虽然小 main 函数只调用了另外一个预定义的集合,但它不能包含在测试覆盖范围内。这个抱怨有点吹毛求疵,但我想如果使用自动测试工具来显示代码行或函数数量的测试覆盖率,就会有问题。

问题

所以,我的问题是:

  • 如何在测试中正确处理此类情况,例如使用 ExUnit?
  • 如何将系统调用与内部逻辑分离并减少样板函数的数量?
  • 是否有任何工具或通用方法在函数式编程中通常如何完成?
0 投票
1 回答
101 浏览

elixir - 具有自定义依赖环境的 Elixir ExUnit 测试

我有一个项目 A,它也依赖于我创建的依赖项 B...

当我想用一个简单的 A 启动测试时mix test,它得到了依赖 B,编译它并在环境中启动它:prod......

这意味着A在:test环境中,B在环境中:prod

我想让测试在环境中启动依赖:dev项(或其他任何东西:prod),有没有办法做到这一点?

0 投票
1 回答
3797 浏览

testing - 没有断言/反驳的 ExUnit,仅依赖于模式匹配?

我正在测试一个函数的返回值。两者中的哪一个是首选方式?

我喜欢第一个,因为我现在不需要,测试需要一个assert语句,并且运行测试时的错误消息更具描述性。Otoh,MatchError带有行号的也应该足够了。

0 投票
1 回答
379 浏览

authentication - 使用 LDAP 进行身份验证时使用 Guardian.Plug.EnsureAuthenticated 通过测试

我按照http://rny.io/elixir/phoenix/ldap/2016/09/20/ldap-authenication-with-phoenix.html上的指南在 Phoenix 中使用 Guardian 设置 LDAP 身份验证。我对 Phoenix 和 Elixir 还很陌生,所以我正在经历设置和测试的过程。

我按照指南进行了所有工作,但是在编写控制器测试时,我无法弄清楚如何通过 Guardian.Plug.EnsureAuthenticated。我遵循了在这里找到的几个指南,但似乎没有任何效果。

有没有人使用 exLDAP 和 Guardian 设置 LDAP 身份验证以及可以提供一些指导的正确用户登录以进行测试?任何帮助,将不胜感激。

以下是我的设置:

lib/ldap_example/guardian_serializer.ex

lib/ldap_example/ldap.ex

网络/控制器/session_controller.ex

结尾

网络/模型/user.ex

我创建了一个 session_controller_text.ex 如下:

最后一次测试失败,因为它将我重定向到登录页面。