004 First Unit Test

004 First Unit Test

Introduction to Unit Testing in Android

Overview of Test Implementations

  • The lecture begins with an introduction to writing the first unit test for functionality within an Android application.
  • It highlights the importance of recognizing both implementation and test implementation dependencies in the build.gradle file, which are crucial for testing.

Understanding JUnit and Espresso

  • JUnit is introduced as the primary unit testing library used in this context, while Espresso will be covered later for UI tests.
  • The distinction between test implementations and android test implementations is explained, emphasizing their relevance to different types of testing.

Instrumented Testing vs. Regular Testing

  • Instrumented tests require an emulator since they involve Android components like fragments or contacts, contrasting with regular tests that do not need one.
  • The structure of Java folders is discussed: real package names versus android test packages, clarifying where each type of test should be written.

Creating Tests: Methods and Best Practices

Prioritizing Regular Tests

  • Emphasis is placed on prioritizing regular tests over instrumented tests due to speed and efficiency; no emulator is needed for regular tests.

Generating Tests Automatically

  • A method for generating tests automatically by right-clicking a class and selecting 'generate' is demonstrated, specifically using JUnit 4 as the default library.

Manual Test Creation

  • While automatic generation is possible, manual creation of test classes is encouraged for better understanding; a new Kotlin class can be created explicitly named (e.g., TaxTesting).

Writing Explicit Test Functions

  • When writing tests, clarity in function naming (e.g., calculateTaxTest) is essential; it helps convey what each function aims to validate clearly.

Best Practices in Writing Unit Tests

Clarity and Expectations in Tests

How to Write Effective Unit Tests in Android

Understanding the Importance of Clarity in Test Naming

  • The length and explicitness of function names in tests can vary; clarity is essential for understanding what each test represents.
  • Using backticks allows for unconventional naming, enabling spaces and other characters to enhance readability.
  • A typical structure for writing tests includes stating what is being tested, the action taken, and the expected result.
  • Example: "calculate tax" is a straightforward name when only two tests are involved, but longer names can provide more context.

Setting Up a Tax Calculation Test

  • To ensure accuracy, define an expected result (e.g., 10 units of tax from an income of 100).
  • If there’s uncertainty about the function's correctness due to its complexity or length, external libraries like Truth can be utilized for testing.

Utilizing the Truth Library for Assertions

  • The Truth library provides fluent assertions specifically designed for Java and Android testing environments.
  • Dependencies must be added to build.gradle files to use Truth effectively within both regular and Android test folders.

Implementing Assertions in Tests

  • Use assertions to verify conditions such as equality or range checks; this helps prevent false positives/negatives during testing.
  • Assertions serve as checkpoints that either confirm expected outcomes or trigger application crashes if conditions aren't met.

Running Tests and Analyzing Results

  • Testing frameworks allow checking various conditions (e.g., whether a number is finite or equal to an expected value).
  • A simple test example confirms that a calculated net tax matches expectations; successful tests yield green indicators in IDE interfaces.

Troubleshooting Failed Tests

  • If a test fails (e.g., expecting 20 but receiving 10), detailed feedback on discrepancies aids debugging efforts.