Post Quantum Cryptography – The Impact on Identity
Unit Testing on Android - Essential Guide to Testing Your Android Apps
1. Unit
Tes)ng
on
Android
Danny
Preussler
GROUPON
DroidCon
Dubai
test
(c)
DaveBleasdale,
CC
by
2.0,
www.flickr.com/photos/sidelong/246816211
2. Groupon
is
the
global
leader
in
local
commerce,
making it easy for people around the world to search !
and discover great businesses at unbeatable prices.
Source: Internal data,, March 2014
WORLDWIDE!
260M+ subscribers 53.9M active customers 500+ markets 900M+ deals sold
2
$5B+ in annual billings 12,000+ global employees
3. Leading
the
way
in
mobile
commerce
Our mobile app is available in 43 countries.
Groupon’s vibrant mobile marketplace connects!
consumers with their local economy
3
Sources: Internal Data; iTunes ranking for US stores available here - https://itunes.apple.com/WebObjects/
MZStore.woa/wa/viewFeature?id=500873243&mt=8&v0=www-itunes25Bcountdown-appstore
Nearly 110 million people worldwide have
downloaded our mobile app at the end of Q4 2014.
One of the 25 most downloaded free
apps of all time
More than 50% of our Global transactions were
completed on a mobile device by the end of Q4
2014
5. What
people
say
about
unit
tes0ng
• Slows
you
down
• I
know
my
code
is
working!
• Only
have
UI
Code
Day
27/365
-‐
Imagina)on..
by
Caden
Crawford,
CC
by
2.0,
flickr.com/
photos/cadencrawford/8422302030
6. What is a Unit Test?
• Small
Opposite
of
an
end-‐to-‐end-‐test
test
the
smallest
unit
possible
• You
should
have
LOTS
of
them
• Fast!!!!
er
by
www.GlynLowe.com,
CC
by
2.0,
flickr.com/photos/glynlowe/10921728045
7. Why
Unit
test?
• Documents
behaviour
• Refactoring
not
possible
without!
• Gives
trust
• Only
slows
down
if
you
don‘t
have
)me
for
quality
code
and
tes)ng
anyway
Day
27/365
-‐
Imagina)on..
by
Caden
Crawford,
CC
by
2.0,
flickr.com/photos/cadencrawford/8422302030
8. Why
Unit
test?
Code
without
Test
=
Legacy
code
Only
Bad
Code
is
untestable!
Day
27/365
-‐
Imagina)on..
by
Caden
Crawford,
CC
by
2.0,
flickr.com/photos/cadencrawford/8422302030
13. New Android Unit Testing
• still experimental
• hdp://tools.android.com/tech-‐docs/unit-‐tes)ng-‐support
• Project
structure:
src/main/java/Foo.java
src/test/java/FooTest.java
• gradle:
android {
testOptions {
unitTests.returnDefaultValues = true
}
Lost
Horizons
-‐
Light
by
Simon
&
His
Camera,
CC
by
2.0
flickr.com/photos/simon__syon/14842606832
14. What
to
test?
Start
your
engine
by
Norlando
Pobre,
CC
by
2.0,
flickr.com/photos/npobre/2601582256
15. Great Wall of China (IV) by isawnyu. CC 2.0 http://
www.flickr.com/photos/isawnyu/7183821643/in/photostream/
Separate Java and Android Code?
16. Great Wall of China (IV) by isawnyu. CC 2.0 http://
www.flickr.com/photos/isawnyu/7183821643/in/photostream/
Separate Java and Android Code?
Android is not Java+UI
Intent, Bundle, SparseArray, Uri.. not fancy device classes!
You will never reuse this on another Java platform,
stop pretending!
Context everywhere
Recreate the System? (interface UI {...} ?)
17. You
can
test
everything!
Typing
the
universe
by
Feliciano
Guimarães,
CC
by
2.0,
flickr.com/photos/jsome1/6097841770
18. „Mock“???
Martin Fowler:
„test-doubles ... pre-programmed with
expectations “
Typing
the
universe
by
Feliciano
Guimarães,
CC
by
2.0,
flickr.com/photos/jsome1/6097841770
19. Typing
the
universe
by
Feliciano
Guimarães,
CC
by
2.0,
flickr.com/photos/jsome1/6097841770
Mock
TelephonyManager mgr =
mock(TelephonyManager.class);
when(mgr.getDeviceId())
.thenReturn("123456");
...
20. Spy
MyPreferences pref =
spy(new MyPreferences(context));
…
verify(pref).saveTitle(same(title));
verify(pref).savePersonalData(anyString());
She
spy
by
Kangrex,
CC
by
2.0;
flickr.com/photos/kangrex/3012574701
21. Building blocks of a Test
public class AndroidAccountsTest {
AccountManager manager;
AndroidAccounts tested;
@Before
public void setup() {...}
@Test
public void should_get_token() {
when(manager.peekAuthToken(....)).thenReturn("token");
String token = tested.getCurrentToken(...)
assertEquals("token", token);
}
}
swivel-‐snot
by
Linus
Bohman,
CC
2.0,
flickr.com/photos/bohman/16062901379
22. Easy...
• Test
u)lity
classes
• Test
JSON
parsing
• Test
API
layer
Duplo
Pac-‐Man
by
Dan
Diemer,
CC
by
2.0,
flickr.com/photos/diemer/192740446
23. Gson gson = GsonFactory.getGson();
@Test
public void should_parse_json_data() {
String values = inputStreamToString(„auth.json"));
AuthRslt rslt = gson.fromJson(values, AuthRslt.class);
assertEquals("AQAAAABwgQ2vVzk-KjiEA3“,
result.getAccessToken());
}
Easy...
Duplo
Pac-‐Man
by
Dan
Diemer,
CC
by
2.0,
flickr.com/photos/diemer/192740446
24. Easy
when
you
do
it
right
• Test
user
interac)on
(click
etc)
• Test
Fragments
and
Ac)vi)es
Lego
small
car.
by
Do-‐Hyun
Kim,
CC
by
2.0,
flickr.com/photos/s)ckkim/6805370739
25. class NavFragment extends InjectedFragment {
Interactor interactor;
@OnClick(R.id.nav_button_checkout)
public void onClickCheckout() {
interactor.moveToCheckout(
getActivity());
}
}
User
interac)on
Lego
small
car.
by
Do-‐Hyun
Kim,
CC
by
2.0,
flickr.com/photos/s)ckkim/6805370739
Test
for
this
is
trivial!
26. Screen
changes
@Test
public void should_do_transaction() {
TransactionUtil transactionsUtil =
mock(TransactionUtil.class),
tested.showPaymentMethods(
transactionsUtil, mock(Purchase.class));
verify(transactionsUtil)
.addAllowingStateLoss(
any(FragmentManager.class),
eq(android.R.id.content),
isA(PaymentFragment.class));
}
Lego
small
car.
by
Do-‐Hyun
Kim,
CC
by
2.0,
flickr.com/photos/s)ckkim/6805370739
27. Screen
changes
Lego
small
car.
by
Do-‐Hyun
Kim,
CC
by
2.0,
flickr.com/photos/s)ckkim/6805370739
• Robolectric
offers
FragmentTranscta)ons
and
life
cycle
method:
• Robolectric
.buildActivity(
Activity.class)
.attach()
.create().....
• Careful,
feature
flaky
28. Screen
changes
Lego
small
car.
by
Do-‐Hyun
Kim,
CC
by
2.0,
flickr.com/photos/s)ckkim/6805370739
• Easier:
Field field =
Fragment.class.getDeclaredField("mActivity");
field.setAccessible(true);
field.set(fragmentInstance, mock(Activity.class);
• You
might
need
also
to
mock
getResources()
29. Harder
but
possible
• Test
UI
code
LEGO
10179
Ul)mate
Collector's
Millenium
Falcon™
by
Do-‐Hyun
Kim,
CC
by
2.0,
flickr.com/photos/s)ckkim/6966161598
30. Test
UI
code
public class BorderPainterTest {
Canvas canvas = mock(Canvas.class);
Circle circle = mock(Circle.class);
BorderPainter tested = new BorderPainter();
@Test
public void should_draw_two_circles() {
...
tested.drawBorder(new RectF(), canvas, circle);
InOrder inOrder = inOrder(canvas);
inOrder.verify(canvas).drawCircle(
anyFloat(), anyFloat(), eq(10f), any(Paint.class));
inOrder.verify(canvas).drawCircle(
anyFloat(), anyFloat(), eq(20f), any(Paint.class));
}
}
LEGO
10179
Ul)mate
Collector's
Millenium
Falcon™
by
Do-‐Hyun
Kim,
CC
by
2.0,
flickr.com/photos/s)ckkim/6966161598
31. Wri)ng
testable
code...
• Clean
Code
• Separa)on
of
Concerns
Manual
Inside
by
Masked
Builder,
CC
by
2.0,
flickr.com/photos/masked-‐builder/8517238602
32. Dependency
Injec)on
helps
• Don‘t
create
dependencies
yourself
• Invert
Control!
• Inject
them!
construct
by
Len
Madhews,
CC
by
2.0;
flickr.com/photos/mythoto/16412713709
Syringe
with
Green
Liquid
by
Andres
Rueda,
CC
by
2.0;
lickr.com/photos/andresrueda/16558374828
33. If
it‘s
hard
to
test...
• Class
is
too
large
• Class
is
doing
too
many
things
• Class
knows
too
many
things
Modified
condi)on/decision
coverage
for
cri)cal
souware
tes)ng
by
Nguyen
Hung
Vu,
CC
by
2.0,
www.flickr.com/photos/vuhung/14621502361
34. Make
it
fail!
Apple
Mini
DisplayPort
adapter
FAIL
by
David
Joyce,
CC
by
2.0,
flickr.com/photos/deapeajay/2969264395
35. 1
method
=
1
test?
• Test
all
cases,
else
you
might
miss
sth
• one
method
should
have
mul)ple
test
(although
coverage
already
reached
with
first)
• Don‘t
be
super
strict
on
units,
some)mes
end
to
end
might
make
sense
i.e.
json
parsing
into
models
with
full
Json
37. When
to
use
Robolectric
• Parcel
Tests
• Arguments/Bundle
Tests
• Resource
loading
Tests
38. Parcel
Tests
with
Robolectric
@RunWith(RobolectricTestRunner.class)
public
class
UserTest
{
Parcel
parcel
=
Parcel.obtain();
User
tested
=
new
User("123",
"456");
@Test
public
void
check_parcel_implementa)on()
{
tested.writeToParcel(parcel,
0);
parcel.setDataPosi)on(0);
User
out
=
User.CREATOR.createFromParcel(parcel);
assertEquals("123",
out.getUser());
assertEquals("456",
out.getPassword());
}
39. Resource
Tests
with
Robolectric
@Test
@Config(qualifiers
=
"en")
public
void
getTotalAuerTaxLong()
{
assertEquals(
"$10.00
Due“,
tested.getTotalAuerTaxLong(1000));
}
40. Layout
tests
with
Robolectric
@Test
public void checkPhoneNumberIsHidden() {
MyActivity activity = new MyActivity();
activity.onCreate();
TextView tv = (TextView)
activity.findViewById(R.id.callText);
assertEquals(View.GONE, tv.getVisibility());
}
41. Dead
End
-‐
mid
by
bennylin0724,
CC
BY
2.0
flickr.com/photos/benny_lin/191393604
42. Test
all
the
Things!
Start
your
engine
by
Norlando
Pobre,
CC
by
2.0,
flickr.com/photos/npobre/2601582256
43. THANK
YOU
Danny
Preussler
GROUPON
Berlin
dpreussler@groupon.com