Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Testing Asynchronous OTP
Search
Andrea Leopardi
September 09, 2021
Programming
0
470
Testing Asynchronous OTP
Andrea Leopardi
September 09, 2021
Tweet
Share
More Decks by Andrea Leopardi
See All by Andrea Leopardi
The World is a Network (and We Are Just Nodes)
whatyouhide
0
160
BEAM: The Perfect Fit for Networks
whatyouhide
1
150
Update from the Elixir team - 2022
whatyouhide
0
350
Elixir Sightseeing Tour
whatyouhide
0
370
Mint - Disrupting HTTP clients
whatyouhide
0
210
BEAM Architecture Handbook
whatyouhide
7
2.7k
The Evolution of a Language
whatyouhide
0
120
Elixir - functional, concurrent, distributed programming for the rest of us
whatyouhide
2
300
Papers we love: Elixir edition
whatyouhide
5
1k
Other Decks in Programming
See All in Programming
C++でシェーダを書く
fadis
6
4.1k
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
170
CSC509 Lecture 13
javiergs
PRO
0
110
Creating a Free Video Ad Network on the Edge
mizoguchicoji
0
120
Outline View in SwiftUI
1024jp
1
330
AWS Lambdaから始まった Serverlessの「熱」とキャリアパス / It started with AWS Lambda Serverless “fever” and career path
seike460
PRO
1
260
What’s New in Compose Multiplatform - A Live Tour (droidcon London 2024)
zsmb
1
480
Hotwire or React? ~アフタートーク・本編に含めなかった話~ / Hotwire or React? after talk
harunatsujita
1
120
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
0
120
型付き API リクエストを実現するいくつかの手法とその選択 / Typed API Request
euxn23
8
2.2k
Amazon Bedrock Agentsを用いてアプリ開発してみた!
har1101
0
340
Nurturing OpenJDK distribution: Eclipse Temurin Success History and plan
ivargrimstad
0
960
Featured
See All Featured
Documentation Writing (for coders)
carmenintech
65
4.4k
Music & Morning Musume
bryan
46
6.2k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
Docker and Python
trallard
40
3.1k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Being A Developer After 40
akosma
87
590k
A Tale of Four Properties
chriscoyier
156
23k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
How STYLIGHT went responsive
nonsquared
95
5.2k
What's in a price? How to price your products and services
michaelherold
243
12k
A designer walks into a library…
pauljervisheath
204
24k
Transcript
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
None
defmodule RollingAverage do use GenServer def start_link(limit), do: # ...
def add(pid, n), do: # ... def average(pid), do: # ... end
None
None
test "add/2" do {:ok, pid} = RollingAverage.start_link() RollingAverage.add(pid, 3) #
Now what? end
None
test "add/2 and average/1" do {:ok, pid} = RollingAverage.start_link(2) RollingAverage.add(pid,
3) RollingAverage.add(pid, 4) assert RollingAverage.average(pid) == 3.5 RollingAverage.add(pid, 5) assert RollingAverage.average(pid) == 4.5 end
None
defmodule RollingList do def new(limit), do: {limit, []} def add({limit,
list}, n), do: # ... def average({_limit, list}), do: # ... end
test "add/2" do rolling_list = RollingList.new(2) assert RollingList.add(rolling_list, 3) ==
{_limit = 2, [3]} end
None
test "add/2" do {:ok, pid} = RollingAverage.start_link(2) RollingAverage.add(pid, 3) state
= :sys.get_state(pid) assert state == {_limit = 2, [3]} end
None
None
test "add/2 and average/1" do {:ok, pid} = start_supervised( {RollingAverage,
_limit = 2} ) # Same as before end
None
def background_work do Task.start(fn -> do_something() end) end
None
None
def background_work(parent, ref) do Task.start(fn -> do_something() send(parent, {ref, :done})
end) end
test "background_work/0" do ref = make_ref() background_work(self(), ref) assert_receive {^ref,
:done} end
None
def background_work do Task.start(fn -> :ok = twitter_module.post() end) end
test "background_work/0" do parent = self() ref = make_ref() Mox.expect(TwitterMock,
:post, fn -> send(parent, ref) :ok end) background_work() assert_receive ^ref end
None
defmodule WeatherChecker do use GenServer def init(_) do :timer.send_interval(5000, self(),
:tick) end def handle_info(:tick, _) do check_weather() end end
test "checking weather periodically" do {:ok, _pid} = WeatherChecker.start_link() Process.sleep(5000
* 1.5) assert weather_checked?() end
None
defmodule WeatherChecker do use GenServer def init(_) do :timer.send_interval(5000, self(),
:tick) end def tick(pid), do: send(pid, :tick) def handle_info(:tick, _) do check_weather() end end
test "checking weather periodically" do {:ok, pid} = WeatherChecker.start_link() WeatherChecker.tick(pid)
assert weather_checked?() end
defmodule WeatherChecker do use GenServer def init(:interval) do :timer.send_interval(5000, self(),
:tick) end def init(:manual) do # No send_interval end end
None
@mix_env Mix.env() def start(_type, _args) do Supervisor.start_link(children(@mix_env), ...) end defp
children(:test), do: [...] defp children(_env), do: [WeatherChecker | ...]
None
None
None
None
test "cleanup after crashes" do Process.flag(:trap_exit, true) {:ok, pid} =
start_supervised(MyServer) Process.exit(pid, :kill) assert cleanup_successful?() end
None
None
None
None
None
None
None
None
None
None