다음과 같이 작동합니다. 소스 코드 ExUnit.Case을보십시오.
처음에는 __using__
매크로를 살펴 봅니다. 테스트 사례에서 매크로를 사용할 때 먼저 호출되기 때문입니다. 특히, 축적으로이 @tag
더 속성의 무리를 등록 here
Enum.each [:ex_unit_tests, :tag, :describetag, :moduletag, :ex_unit_registered],
&Module.register_attribute(__MODULE__, &1, accumulate: true)
있습니다. Module.register_attribute/3의 문서를 읽고 anytime 속성이 호출되면 값이 이전 속성 목록에 추가된다는 것을 알 수 있습니다.
그런 test/3
매크로, 특히 here
quote bind_quoted: [var: var, contents: contents, message: message] do
name = ExUnit.Case.register_test(__ENV__, :test, message, [])
def unquote(name)(unquote(var)), do: unquote(contents)
end
주 ExUnit.Case.register_test/4
에 대한 호출을 확인합니다. 특히, 그것을 here
tag = Module.delete_attribute(mod, :tag)
을 찾고은 여기까지 태그를 가져, 그들을 삭제합니다. 그리고 태그 및 테스트의 이름을함으로써, 그것은 또 다른 속성 내부 태그와 함께 테스트를 저장 (here)
test = %ExUnit.Test{name: name, case: mod, tags: tags}
Module.put_attribute(mod, :ex_unit_tests, test)
를 호출합니다.
그리고 마침내
, 여기
@doc false
defmacro __before_compile__(_) do
quote do
def __ex_unit__(:case) do
%ExUnit.TestCase{name: __MODULE__, tests: @ex_unit_tests}
end
end
end
__ex_unit__/1
각 케이스 내부 테스트의 정보를 얻을 수 ExUnit.Runner.run_case/3에 호출되는 기능을 확인합니다.
포인트가 보입니까? 누적 된 속성을 사용하십시오. 매크로 호출 내에서 항상 속성의 현재 값을 가져 와서 지우고 그 값으로 원하는 모든 작업을 수행하는 함수를 사용하십시오. 매크로가 호출 될 때마다 항상 알 수 있기 때문입니다.
자세한 설명이 필요하면 의견이 분명하기를 바랍니다.
추신. 나는 이것을 알아 내기 위해 소스 코드를 읽었을 뿐이다. 그것이 어떻게 작동하는지 아는 것은 흥미로웠다.
이 페이지를 본 적이 있습니까? http://elixir-lang.org/docs/master/ex_unit/ExUnit.Case.html 특히이 페이지의이 섹션은 귀하의 질문과 관련이있는 것으로 보입니다 : http://elixir-lang.org/docs/master/ex_unit/ ExUnit.Case.html # module-tags이 페이지에 당신에게 불분명 한 것이 있습니까? 귀하의 질문은 나에게 분명하지 않습니다. –
나는 ExUnit이 기능에 대한 주석으로 작용하는 @tags를 가지고 있음을 보여 주었다. 나의 질문은 어떻게 달성 했는가이다.실제로 문제를 해결하면서 문제를 해결했습니다. 이제는 실제로 컴파일시 이러한 주석을 사용하여 유용한 모든 작업을 수행 할 수있는 또 다른 문제가 있습니다. https://github.com/chrisjowen/annotatable – Owen
알았어. 내 의견을 알고 싶은 걸 몹시 분명하게 알리지 못한다는 신호로 받아 들여라. –