Testing Android Components, @Before & @After - Testing on Android

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hey guys welcome back to new video in this video you're going to learn how we can test android components such as a context so we will write a function that takes a context as a parameter and you will learn how we can test that and you will also learn about the before and the after annotation in junit but first of all let me quickly go through the solution of the homework from the last video where i gave you those two functions that fibonacci function and the check braces function and you should write test cases to check if those functions are working properly and the solution is both of those functions are not working properly in the fibonacci function this must be n minus 1 so that it works and the check braces function is not working as well because let's say we have braces like this then this would return true even though that is not correct since this only considers the the amount of the braces and not the order in which they are placed so i hope you recognize that and in the best case also corrected those functions so back in the project we created in the last video you can also create a new project but just make sure that you have the same dependencies as in the last video then what i want to do here is i want to create a class that contains a function and that function will take a context a resource id of the string and a string and this function will return if the string of this resource id is the same as the string we passed as a parameter and since accessing resources in android requires the context we need to do something differently here as in the last video in the last video we just used um tests that run on the jvm but this time we rely on an android component the context so what we need to do is we need to put our test in the android test directory so what i will do is i will go to our main package so our main source set with our main activity in our registration util from the last video and inside of that i will create a new carton follow class which i will call re source comparer and that is a class this time not an object because i want to show you how we can do it with classes um we need to create an instance of so last time we just had a singleton for which we didn't need an instance but this time we do it with a class so we need that press enter here to create that class yes i want to add that to git and inside of this class i want to create the function i talked about and that will be a function is equal which will take the context it will take a resource id res id which is of type integer and it will take a string with which we want to compare the string at the resource id which is a string of course and the return type will be a boolean so whether the string at that resource id is equal to the string we passed here and let's actually also implement that function right away that is not what we would normally do with test driven development but this video's focus is on testing android components and this is a single line anyways here so let's quickly do that we simply return context dot get string res id and check if that is equal to the string we pass as a parameter so let's actually create a test class for this resource comparer class here if you remember from the last video we right click on this class go to generate and select test here then make sure to select junit 4 and the class name is fine that is the convention for test classes and then we simply click on ok and this time we want to select the android test directory because this function this is equal function needs a context object which is specific to android so click ok and then this class will be generated here in this android test directory you can see here here it is resource compare our test we can open that class up and write our test cases so what exactly is different here as in the last video on the one hand we of course somehow need to get the context or reference to a context object we can use in our test case but on the other hand we also rely on a class we need an instance of so the last time as i said we had a singleton this registration util class for which we didn't need an instance but this time we have the class resource comparer for which we do need that let's actually first choose the intuitive approach by creating a val resource comparer and set that equal to a new resource comparer so that we have that globally and we can access that resource comparer in all of our test cases and we can actually make that private as well and this is the bad practice so don't do this in your real projects but i just want to show you that this still works but then afterwards um explain why this is bad and next we can write our actual test cases so we annotate that with add test and that will be a function and here in android we sadly cannot use those backticks i don't really know the reason for that because let's say hello world this doesn't work as you can see um identify not allowed in android projects this only works if you have tests in the test directory so you can choose which naming you want here if you want to stay consistent then you can choose the naming that i will suggest here also in the test directory but if you don't want or don't need to be consistent then you can choose backticks in the test directory and the naming that i suggest in the android test directory so what we will do here is we will just um describe what this test case will test and what we expect it to return so in this case string resource same as a given string then we make an underscore and we write returns true so if the string resource is the same as the given string of that function then we expect the test to return true or then we expect the actual function that we test here to return true and that is the official naming convention for test cases if you can't use that backtick naming and in here we can now get a reference to a context object and since we are inside of our android test directory and that is very easy we can write val context is equal to application provider dot get application context and here we simply need to pass the type of that context which is just context and that is how we can get the context object in the android test directory for our test cases now we can call our functions so val result is equal to our resource comparer that we created above and we want to test the is equal function so is equal we pass our context our resource id so our.string and we only have a single string here our app name and here i will choose my app name so unit testing youtube you of course need to choose your own project name for that so it really returns true otherwise it won't return true and then we can use insert that and it's just as in the last video this is the assert that function from junit which we don't want we want the assert that function from truth so we remove the junit assert import here and we import the insert that function from the truth library here and we want to assert that the result is true and that is already our test case then we can copy the test case and make the same for if if the string is a different string than the string resource and then it should return false so returns false and string restores different as a given string we write something else here that is different and we assert that this is false and now let's actually run our tests so all of our tests inside of this resource compare test class by clicking on this play button next to that class and click on run resource comparer test and then wait a little moment and you can see the emulator starts now because this is not a normal test anymore that runs on the jvm instead it needs the emulator to run on because we rely on that context object here so let's wait a little moment and you can see all of our tests succeeded so exactly as we expected here but you might still wonder why this is a bad practice to initialize this resource comparer directly as a global variable even even though we still need that resource comparer in both of our test cases and if you listen carefully in the last video or not in the last video in the video where i talked about what good tests are then you already know the answer and the answer is all of our test cases should run independent of each other and right now they don't because they rely on the same instance of resource comparer and that is not independent anymore so in our case this is not a problem because our resource comparer only contains this single function and it doesn't have any member variables or something like that but let's imagine this class that you test here has an internal counter so a counter member variable that would mean that the counter variable is different for each of your test cases so let's say this test case would increment the counter by 1 and then this test case would already start with a counter that is equal to one and we don't have any influence on the order these junit tests are executed in so it could be that this test case is first or this test cases first we don't have any impact on that basically and if we were always do it like this here that we initialize our variables here globally or objects then this would very often produce flaky tests so tests that sometimes succeed and sometimes fail and we want to prevent that at all costs so let's actually try out the next intuitive approach let's change this to a private latent var we don't initialize this here yet instead we just declare this as a resource comparer and then we just initialize this in each of our test cases so each of our test cases has its own instance so resource comparer is equal to new resource comparer and then we can copy that line and paste it in this test case and if we now relaunch our tests wait a little moment then you can see that they still run so this time this is much better because each of our test cases has its own instance of resource comparer because it just creates that instance at the start of the test case but the problem with this is let's say we have like 30 test cases inside of this class and in each of those test cases we initialize that variable at first then we would have 30 additional lines just for initialization of an object and that is a lot of boilerplate code we don't want here and luckily junit has a very cool solution for that so we can remove that here and with the junit we can create a so-called setup function we write function setup and inside of this function we simply write the logic that we want to execute before the run of every test case so we initialize this resource comparer here and then we annotate this function with add before so what this will do is it will execute this piece of code before this test case runs and before this test case one so before every of our test case runs we initialize this object so if we now run this again then surprise surprise it will still work as you can see and if there is a before annotation then there's also an after annotation which we don't need here but very often you do need that so we can annotate something with add after and that function is usually called tear down and here you can just destroy your objects that you created before in this case as i said it doesn't make any sense because the garbage collector will do that here but for example if you test a room database then you want to close the database after every test case and yeah when we actually implement our actual app that we test here our mvvm project and then we will also need this after function quite often so i really hope this video made sense to you and help you to understand how to test android components or actually only the context here you don't know how to test fragments yet but you will also understand that in this series if you haven't subscribed to my channel yet then quickly make sure to do that click on the subscribe button and yeah get regular android content every second day high quality just as usual have a nice day see you next video bye bye [Music] you
Info
Channel: Philipp Lackner
Views: 14,931
Rating: 4.9940476 out of 5
Keywords: testing, android, test, test case, junit, mockito, mock, fake, stub, tdd, test driven development, intellij, android studio, unit test, unit testing, integration test, integrated test, end to end test, ui test, kotlin, mvvm, live data, coroutines, dagger, retrofit, room, database, roboelectric, android test, jvm, flaky test, development, programming, git
Id: PsoLeJOh30o
Channel Id: undefined
Length: 14min 56sec (896 seconds)
Published: Thu Aug 20 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.