Skip to content

Commit c3d6a96

Browse files
author
José Valim
committed
Consider load time on ExUnit reports, closes #893
1 parent d238d50 commit c3d6a96

File tree

6 files changed

+62
-37
lines changed

6 files changed

+62
-37
lines changed

lib/ex_unit/lib/ex_unit.ex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ defmodule ExUnit do
8181
:application.start(:ex_unit)
8282

8383
configure(options)
84+
ExUnit.Server.start_load
8485

8586
System.at_exit fn
8687
0 ->
@@ -118,7 +119,7 @@ defmodule ExUnit do
118119
Returns the number of failures.
119120
"""
120121
def run do
121-
{ async, sync } = ExUnit.Server.cases
122-
ExUnit.Runner.run async, sync, ExUnit.Server.options
122+
{ async, sync, options, load_us } = ExUnit.Server.start_run
123+
ExUnit.Runner.run async, sync, options, load_us
123124
end
124125
end

lib/ex_unit/lib/ex_unit/cli_formatter.ex

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ defmodule ExUnit.CLIFormatter do
1818
pid
1919
end
2020

21-
def suite_finished(id, ms) do
22-
:gen_server.call(id, { :suite_finished, ms }, @timeout)
21+
def suite_finished(id, run_us, load_us) do
22+
:gen_server.call(id, { :suite_finished, run_us, load_us }, @timeout)
2323
end
2424

2525
def case_started(_id, _test_case) do
@@ -44,8 +44,8 @@ defmodule ExUnit.CLIFormatter do
4444
{ :ok, Config.new }
4545
end
4646

47-
def handle_call({ :suite_finished, ms }, _from, config) do
48-
print_suite(config.counter, config.test_failures, config.case_failures, ms)
47+
def handle_call({ :suite_finished, run_us, load_us }, _from, config) do
48+
print_suite(config.counter, config.test_failures, config.case_failures, run_us, load_us)
4949
{ :stop, :normal, length(config.test_failures), config }
5050
end
5151

@@ -82,19 +82,19 @@ defmodule ExUnit.CLIFormatter do
8282
super
8383
end
8484

85-
defp print_suite(counter, [], [], ms) do
85+
defp print_suite(counter, [], [], run_us, load_us) do
8686
IO.write "\n\n"
87-
IO.puts "Finished in #{format_ms ms} seconds"
87+
print_time(run_us, load_us)
8888
IO.puts success("#{counter} tests, 0 failures")
8989
end
9090

91-
defp print_suite(counter, test_failures, case_failures, ms) do
91+
defp print_suite(counter, test_failures, case_failures, run_us, load_us) do
9292
IO.write "\n\nFailures:\n\n"
9393
num_fails = Enum.reduce Enum.reverse(test_failures), 1, print_test_failure(&1, &2, File.cwd!)
9494
Enum.reduce Enum.reverse(case_failures), num_fails, print_case_failure(&1, &2, File.cwd!)
9595
num_invalids = Enum.count test_failures, fn test -> test.invalid end
9696

97-
IO.puts "Finished in #{format_ms ms} seconds"
97+
print_time(run_us, load_us)
9898

9999
num_fails = num_fails - 1
100100
message = "#{counter} tests, #{num_fails} failures"
@@ -160,6 +160,18 @@ defmodule ExUnit.CLIFormatter do
160160
Enum.each stacktrace, fn(s) -> IO.puts stacktrace_info format_entry(s, cwd) end
161161
end
162162

163+
defp print_time(run_us, nil) do
164+
IO.puts "Finished in #{run_us |> normalize_us |> format_us} seconds"
165+
end
166+
167+
defp print_time(run_us, load_us) do
168+
run_us = run_us |> normalize_us
169+
load_us = load_us |> normalize_us
170+
171+
ms = run_us + load_us
172+
IO.puts "Finished in #{format_us ms} seconds (#{format_us load_us}s on load, #{format_us run_us}s on tests)"
173+
end
174+
163175
defp pad(binary, max) do
164176
remaining = max - size(binary)
165177
if remaining > 0 do
@@ -169,12 +181,16 @@ defmodule ExUnit.CLIFormatter do
169181
end
170182
end
171183

172-
defp format_ms(ms) do
173-
if ms < 100000 do
174-
"0.0#{div(ms, 10000)}"
184+
defp normalize_us(us) do
185+
div(us, 10000)
186+
end
187+
188+
defp format_us(us) do
189+
if us < 10 do
190+
"0.0#{us}"
175191
else
176-
ms = div ms, 100000
177-
"#{div(ms, 10)}.#{rem(ms, 10)}"
192+
us = div us, 10
193+
"#{div(us, 10)}.#{rem(us, 10)}"
178194
end
179195
end
180196

lib/ex_unit/lib/ex_unit/formatter.ex

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@ defmodule ExUnit.Formatter do
77
use Behaviour
88

99
@type id :: term
10-
@type test_case :: module
11-
@type test :: atom
10+
@type test_case :: ExUnit.TestCase.t
11+
@type test :: ExUnit.Test.t
1212
@type result :: { kind :: atom, reason :: term, stacktrace :: list } | nil
13+
@type run_us :: pos_integer
14+
@type load_us :: pos_integer | nil
1315

1416
defcallback suite_started(opts :: list) :: id
15-
defcallback suite_finished(id, miliseconds :: pos_integer) :: non_neg_integer
17+
defcallback suite_finished(id, run_us, load_us) :: non_neg_integer
1618

1719
defcallback case_started(id, test_case) :: any
1820
defcallback case_finished(id, test_case) :: any
1921

20-
defcallback test_started(id, test :: ExUnit.Test.t) :: any
21-
defcallback test_finished(id, test :: ExUnit.Test.t) :: any
22+
defcallback test_started(id, test) :: any
23+
defcallback test_finished(id, test) :: any
2224
end

lib/ex_unit/lib/ex_unit/runner.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ defmodule ExUnit.Runner do
44
defrecord Config, formatter: ExUnit.CLIFormatter, formatter_id: nil,
55
max_cases: 4, taken_cases: 0, async_cases: [], sync_cases: []
66

7-
def run(async, sync, opts) do
7+
def run(async, sync, opts, load_us) do
88
config = Config[max_cases: :erlang.system_info(:schedulers_online)]
99
config = config.update(opts)
1010

11-
{ ms, config } =
11+
{ run_us, config } =
1212
:timer.tc fn ->
1313
loop config.async_cases(async).sync_cases(sync).
1414
formatter_id(config.formatter.suite_started(opts))
1515
end
1616

17-
config.formatter.suite_finished(config.formatter_id, ms)
17+
config.formatter.suite_finished(config.formatter_id, run_us, load_us)
1818
end
1919

2020
defp loop(Config[] = config) do

lib/ex_unit/lib/ex_unit/server.ex

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ defmodule ExUnit.Server do
44
@timeout 30_000
55
use GenServer.Behaviour
66

7-
defrecord Config, options: [], async_cases: [], sync_cases: []
7+
defrecord Config, options: [], async_cases: [], sync_cases: [],
8+
start_load: nil
89

910
def start_link(options) do
1011
:gen_server.start_link({ :local, __MODULE__ }, __MODULE__, options, [])
1112
end
1213

1314
## Before run API
1415

16+
def start_load() do
17+
:gen_server.cast(__MODULE__, :start_load)
18+
end
19+
1520
def add_async_case(name) do
1621
:gen_server.cast(__MODULE__, { :add_async_case, name })
1722
end
@@ -26,12 +31,8 @@ defmodule ExUnit.Server do
2631

2732
## After run API
2833

29-
def options do
30-
:gen_server.call(__MODULE__, :options, @timeout)
31-
end
32-
33-
def cases do
34-
:gen_server.call(__MODULE__, :cases, @timeout)
34+
def start_run() do
35+
:gen_server.call(__MODULE__, :start_run, @timeout)
3536
end
3637

3738
## Callbacks
@@ -40,20 +41,25 @@ defmodule ExUnit.Server do
4041
{ :ok, Config[options: options] }
4142
end
4243

43-
def handle_call(:options, _from, config) do
44-
{ :reply, config.options, config }
45-
end
44+
def handle_call(:start_run, _from, config) do
45+
load_us =
46+
if start_load = config.start_load do
47+
:timer.now_diff(:os.timestamp, start_load)
48+
end
4649

47-
def handle_call(:cases, _from, config) do
4850
{ :reply,
49-
{ config.async_cases, config.sync_cases },
50-
config.async_cases([]).sync_cases([]) }
51+
{ config.async_cases, config.sync_cases, config.options, load_us },
52+
config.async_cases([]).sync_cases([]).start_load(nil) }
5153
end
5254

5355
def handle_call(request, from, config) do
5456
super(request, from, config)
5557
end
5658

59+
def handle_cast(:start_load, config) do
60+
{ :noreply, config.start_load(:os.timestamp) }
61+
end
62+
5763
def handle_cast({:add_async_case, name}, config) do
5864
{ :noreply, config.update_async_cases [name|&1] }
5965
end

lib/ex_unit/test/ex_unit_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ defmodule ExUnit.NilFormatter do
77
:ok
88
end
99

10-
def suite_finished(:ok, _ms) do
10+
def suite_finished(:ok, _run_us, _load_us) do
1111
1
1212
end
1313

0 commit comments

Comments
 (0)