CS50P - Lecture 5 - Unit Tests

3 min read 1 month ago
Published on Aug 01, 2024 This response is partially generated with the help of AI. It may contain inaccuracies.

Table of Contents

Introduction

This tutorial provides a comprehensive guide to writing unit tests in Python, drawing from a CS50 lecture. Unit testing is a crucial practice that helps ensure your code functions correctly by systematically checking individual units of code, usually functions. By the end of this tutorial, you'll understand how to write tests for your functions, handle exceptions, and utilize third-party libraries like pytest to simplify the testing process.

Chapter 1: Understanding Unit Tests

  • Definition: Unit tests are small, automated tests that check the functionality of specific sections of your code, particularly functions.
  • Why Unit Tests Matter:
    • They help catch bugs early.
    • They ensure that changes to code do not break existing functionality.
    • They provide documentation for expected behavior of functions.

Chapter 2: Writing a Simple Function and Its Tests

Creating a Basic Function

  1. Define the Function: Create a function to calculate the square of a number.

    def square(n):
        return n * n
    
  2. Create a Main Function: This function will prompt the user for input and print the square.

    def main():
        x = int(input("What's x? "))
        print(f"{x} squared is {square(x)}")
    
    if __name__ == "__main__":
        main()
    

Writing Tests for the Function

  1. Setup a New Test File: Create a new file named test_calculator.py.

  2. Import the Function:

    from calculator import square
    
  3. Define Test Functions:

    def test_square():
        assert square(2) == 4
        assert square(3) == 9
        assert square(-2) == 4
        assert square(-3) == 9
        assert square(0) == 0
    
  4. Run the Tests: Execute the test file to verify functionality.

    python -m pytest test_calculator.py
    

Chapter 3: Handling Exceptions in Tests

  • Testing for Exceptions: Use pytest to check if the correct errors are raised for invalid inputs.
    def test_square_type_error():
        with pytest.raises(TypeError):
            square("cat")
    

Chapter 4: Utilizing pytest for Efficient Testing

  • Installation: Install pytest using pip.

    pip install pytest
    
  • Simplifying Tests: Remove boilerplate code such as main function calls and try/except blocks.

  • Running Tests: Simply run pytest in the terminal to execute all test cases in the specified file or folder.

Chapter 5: Organizing Tests

Creating a Test Directory

  1. Create a Folder: Organize your tests by creating a folder named tests.

    mkdir tests
    
  2. Place Test Files: Move your test files into this directory.

  3. Using __init__.py: Create an empty __init__.py file in the tests folder to treat it as a package.

  4. Running Tests from a Folder: Use the command below to execute all tests within the folder.

    pytest tests/
    

Conclusion

By employing unit tests in your Python code, you can enhance the reliability and maintainability of your applications. The process of writing tests helps you catch errors before your code goes live, ensuring that your functions behave as expected under various conditions. Consider integrating more tests as your application grows and explore additional edge cases for thorough validation. To further enhance your testing skills, practice writing tests for different types of functions and datasets.