Unit Testing Flashcards

1
Q

What is unit testing in software development?

A

Unit testing is a software testing technique where individual components or functions of a software application are tested in isolation to ensure that they perform correctly as per their specifications.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What is the primary goal of unit testing?

A

The primary goal of unit testing is to verify that each unit of code (e.g., functions, methods, classes) works correctly in isolation, identifying and fixing bugs early in the development process.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What are the key characteristics of a good unit test?

A

Good unit tests are automated, isolated, repeatable, and provide clear pass/fail results. They should cover various scenarios, including edge cases, and be independent of external dependencies.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What is a test case in unit testing?

A

A test case is a specific scenario or condition that a unit test evaluates to check if the code behaves as expected. Test cases are designed to cover different aspects of the code’s functionality.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What is a test framework, and how does it relate to unit testing?

A

A test framework is a set of tools, libraries, and conventions used to organize, execute, and report on unit tests. It provides a structure for writing, organizing, and running tests efficiently.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What is the purpose of mock objects in unit testing?

A

Mock objects are used to simulate external dependencies or collaborators in unit tests. They allow developers to isolate the unit being tested and control the behavior of external components.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What is test-driven development (TDD), and how does it relate to unit testing?

A

Test-driven development (TDD) is a development approach where tests are written before writing the actual code. Developers follow a cycle of writing tests, implementing code to pass the tests, and then refactoring. TDD promotes unit testing as a core practice.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Why is regression testing important in the context of unit testing?

A

Regression testing ensures that new changes or features added to the codebase do not introduce new defects or break existing functionality. Unit tests play a significant role in regression testing by quickly identifying issues.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

What are some popular unit testing frameworks for different programming languages?

A

Popular unit testing frameworks include JUnit for Java, NUnit for .NET, pytest for Python, RSpec for Ruby, and Jasmine for JavaScript, among others.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

How can code coverage metrics help in unit testing?

A

Code coverage metrics measure the percentage of code that is executed by unit tests. They help identify areas of code that are not covered by tests, ensuring comprehensive test coverage.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What are flaky tests in the context of software testing?

A

Flaky tests, also known as unstable tests or nondeterministic tests, are automated tests that produce inconsistent results upon multiple test executions, even if the application code remains unchanged.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What are some common reasons for tests to become flaky?

A

Flaky tests can result from various factors, including:

Timing Issues: Tests relying on specific timing conditions can fail if the system’s performance varies.

Concurrency Problems: Tests involving multiple threads or processes can lead to race conditions.

External Dependencies: Tests interacting with external services, databases, or network resources may fail due to external changes or network issues.

Order Dependency: Tests that rely on the order of execution can become flaky if executed in a different order.

Test Data: Flaky tests may occur if test data changes or is not properly isolated.

Environment Variability: Differences in test environments (e.g., hardware, software, configurations) can lead to flakiness.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Why are flaky tests problematic in software development?

A

Flaky tests can be problematic for several reasons:

They erode trust in the testing process as developers may ignore or mistrust test failures.
They waste development time and resources in investigating and fixing non-existent issues.
They can lead to false bug reports and unnecessary code changes.
They may hide actual defects by masking them with random test failures.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

How can flaky tests be identified and mitigated?

A

To identify and mitigate flaky tests:

Rerun Tests: Rerun failing tests multiple times to confirm flakiness. If a test fails intermittently, it’s likely flaky.

Isolate Tests: Ensure that tests are isolated from each other and don’t share state or dependencies.

Fix Timing Issues: Use explicit waits, timeouts, or mock time to handle timing-related issues.

Mock External Dependencies: Replace external services with mocks or stubs to eliminate external factors.

Randomize Test Order: Execute tests in random order to uncover order-dependent issues.

Reset State: Reset the application or test environment to a known state before each test.

Use Stable Environments: Ensure that test environments are stable and consistent.

Monitor and Investigate: Continuously monitor test results and investigate failures promptly.

Documentation: Document known flaky tests and their status to inform the development team.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Are there tools or frameworks to help identify and manage flaky tests?

A

Yes, there are tools and frameworks designed to help identify and manage flaky tests. Some of these include:

Test Retry Mechanisms: Some test runners allow you to automatically retry failed tests a certain number of times to identify flakiness.

Test Flakiness Detection Tools: There are tools like “Flaky Tests Detection” plugins for test frameworks that help identify flaky tests based on historical data.

Continuous Integration (CI) Pipelines: CI systems can be configured to rerun failed tests, and the number of retries can be adjusted based on historical data.

Custom Test Wrappers: Developers can create custom test wrappers that automatically rerun tests and report flaky ones.

Logging and Reporting: Comprehensive test logging and reporting can help identify patterns of flakiness over time.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

How can a development team prevent flaky tests from being introduced in the first place?

A

To prevent flaky tests:

Follow best practices for writing stable and deterministic tests.
Isolate tests from external dependencies and shared state.
Use explicit synchronization mechanisms when dealing with timing-related operations.
Regularly review and refactor tests to maintain their stability.
Maintain a clean and consistent test environment.
Encourage communication within the team about test flakiness to address issues promptly.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

What role does test automation play in managing flaky tests?

A

Test automation can both contribute to and help mitigate flaky tests. While poorly designed automated tests can introduce flakiness, well-designed automated tests can detect flakiness early and facilitate rapid retesting and debugging. Automation also allows for rerunning tests frequently, increasing the chances of identifying flaky tests.

18
Q

What is the purpose of the @Mock annotation in Mockito?

A

The @Mock annotation is used to create a mock object of a class or interface in Mockito.

19
Q

How is the @Spy annotation different from the @Mock annotation in Mockito?

A

The @Spy annotation is used to create a spy object, which retains the real behavior of the object while allowing you to stub or verify specific methods. The @Mock annotation creates a traditional mock object with no real behavior.

20
Q

What does the @Captor annotation help you do in Mockito?

A

The @Captor annotation is used to create an ArgumentCaptor, which helps capture arguments passed to methods during method invocations on mock objects. It is often used for verification purposes.

21
Q

How do you inject mock or spy dependencies into the class under test using Mockito?

A

You can use the @InjectMocks annotation to inject mock or spy dependencies into the class under test.

22
Q

What is the purpose of the @RunWith(MockitoJUnitRunner.class) annotation in Mockito?

A

The @RunWith(MockitoJUnitRunner.class) annotation is used to run the test class with the MockitoJUnitRunner. It initializes mocks annotated with @Mock and manages the Mockito lifecycle.

23
Q

How can you manually initialize mock objects when not using the MockitoJUnitRunner?

A

You can manually initialize mock objects using the @MockitoAnnotations.initMocks(this) annotation. It is typically used in the @Before setup method of the test class.

24
Q

Mockit Annotations

A

@Mock:

Usage: @Mock
Description: This annotation is used to create a mock object of a class or interface. It initializes a mock object and makes it available for use in the test class.
@Spy:

Usage: @Spy
Description: The @Spy annotation is used to create a spy object, which is a partially mocked object. A spy retains the real behavior of the object but allows you to stub or verify specific methods.
@Captor:

Usage: @Captor
Description: The @Captor annotation is used to create an ArgumentCaptor, which is used to capture arguments passed to methods during method invocations on mock objects. It’s often used in conjunction with verification.
@InjectMocks:

Usage: @InjectMocks
Description: The @InjectMocks annotation is used to inject mock or spy dependencies into the class under test. It identifies the target class where mock dependencies should be injected.
@RunWith(MockitoJUnitRunner.class):

Usage: @RunWith(MockitoJUnitRunner.class)
Description: This annotation is used at the class level to run the test class with the MockitoJUnitRunner. It initializes mocks annotated with @Mock, and it manages the Mockito lifecycle.
@MockitoAnnotations.initMocks(this):

Usage: @MockitoAnnotations.initMocks(this)
Description: Instead of using the MockitoJUnitRunner, you can manually initialize mock objects using this annotation. It’s typically used in the @Before setup method of the test class.

25
Q

Mokito Annotations Example

A

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class MyServiceTest {
@Mock
private SomeDependency someDependency;
@Spy
private AnotherDependency anotherDependency;
@Captor
private ArgumentCaptor<String> stringCaptor;
@InjectMocks
private MyService myService;
@Before
public void setUp() {
// Initializes annotated mocks, spies, and injects dependencies
MockitoAnnotations.initMocks(this);
}
@Test
public void testSomeMethod() {
// Define mock behavior using when() and verify() as needed
when(someDependency.someMethod()).thenReturn("Mocked Value");
// Perform test actions on myService
String result = myService.someMethod();
// Use ArgumentCaptor to capture method arguments for verification
verify(anotherDependency).processString(stringCaptor.capture());
// Perform assertions and verifications
assertEquals("Expected Result", result);
assertEquals("Captured Argument", stringCaptor.getValue());
}
}</String>

26
Q

AAA

A

“Arrange-Act-Assert” (AAA) pattern is a common structure used in unit testing to organize test cases. Each test case consists of three main sections: “Arrange,” where you set up the test environment, “Act,” where you perform the action or operation to be tested, and “Assert,” where you verify the expected outcomes.

27
Q

What is the purpose of the “Arrange” phase in the AAA pattern?

A

The “Arrange” phase is where you set up the initial state or context for your unit test. This includes preparing input data, creating objects, and configuring the environment to ensure that the test conditions are met.

28
Q

What does the “Act” phase entail in the AAA pattern?

A

The “Act” phase is where you trigger the specific action, method, or operation that you want to test. This step represents the execution of the functionality under test.

29
Q

What is the purpose of the “Assert” phase in unit testing using AAA?

A

The “Assert” phase is where you make assertions or checks to verify that the actual results or outputs of the action in the “Act” phase match the expected outcomes or conditions defined by your test case.

30
Q

Can you provide an example of something you might do during the “Arrange” phase of a unit test?

A

During the “Arrange” phase, you might initialize objects, set up mock data, configure parameters, and prepare the test environment. For example, you could create mock database connections or instantiate classes with specific initial states.

31
Q

What is an example of an action you would perform in the “Act” phase of a unit test?

A

In the “Act” phase, you would invoke the method or function being tested with the prepared data and input parameters. For instance, you might call a method that calculates the total price of items in a shopping cart.

32
Q

How would you use the “Assert” phase to check the correctness of your test in unit testing?

A

In the “Assert” phase, you would use assertions or conditions to compare the actual results generated by the action in the “Act” phase to the expected results or outcomes defined in your test case. For example, you might assert that the calculated total price matches the expected total price.

33
Q

Why is the AAA pattern important in unit testing?

A

The AAA pattern provides a clear and structured approach to writing unit tests. It separates the setup, execution, and verification phases, making tests more readable, maintainable, and easier to troubleshoot.

34
Q

What is the purpose of the @SpringBootTest annotation in Spring Boot?

A

The @SpringBootTest annotation is used to specify that a particular class is a Spring Boot integration test. It loads the Spring application context and provides a way to test the application as a whole.

35
Q

What happens when you apply the @SpringBootTest annotation to a test class?

A

When @SpringBootTest is used, it triggers the loading of the entire Spring application context, including all the beans, configurations, and components, allowing you to test the Spring Boot application in its entirety.

36
Q

What layers of a Spring Boot application can you test using @SpringBootTest?

A

@SpringBootTest allows you to test various layers of a Spring Boot application, including controllers, services, repositories, and their interactions, providing integration testing capabilities.

37
Q

Can you customize the Spring application context loaded by @SpringBootTest?

A

Yes, you can customize the application context loaded by @SpringBootTest using attributes such as classes, properties, and webEnvironment. These attributes allow you to control which components and configurations are included and configure the web environment.

38
Q

What are the available options for configuring the web environment when using @SpringBootTest?

A

The @SpringBootTest annotation provides three options for configuring the web environment:
WebEnvironment.MOCK: Loads a mock web application context.
WebEnvironment.RANDOM_PORT: Starts the application on a random port.
WebEnvironment.DEFINED_PORT: Starts the application on a defined port.

39
Q

How can you perform HTTP requests and test controllers using @SpringBootTest?

A

You can use the MockMvc framework in combination with @AutoConfigureMockMvc annotation to simulate HTTP requests and test controllers as part of your integration tests.

40
Q

Can you perform database integration testing with @SpringBootTest?

A

Yes, you can perform database integration testing by configuring and using embedded databases like H2 or by connecting to a real database with a test-specific configuration when using @SpringBootTest.

41
Q

What is the difference between using @SpringBootTest and using test slices (e.g., @WebMvcTest, @DataJpaTest)?

A

@SpringBootTest loads the entire application context, making it suitable for end-to-end or integration testing. Test slices load only specific parts of the application context, making them more focused and efficient for testing individual components or layers.