GitHub Copilot - Patterns & Exercises
GitHub 🌟
en 🇬🇧
en 🇬🇧
  • Introduction
  • Contributing to the Project
  • General
    • Code completion
    • Comment to code
    • Code to comment
    • Quick Q&A
    • Regular expression
    • Language translation
    • Type hinting
    • Code to document
    • Object generation from structured data
    • Showing examples
  • Client Side Tips
    • Copilot snnipet handling
    • GitHub Copilot Shortcuts
    • Go to definition
    • Pin the files you need
  • Design Patterns
    • AI readable naming convention
    • Consistent coding style
    • High-level architecture first
    • Working on small chunks
    • Context-less Architecture
    • Eliminating a tiny OSS dependency
  • Collaboration
    • AI friendly documentation
    • Coaching on prompts
  • Test
    • Creating unit tests
    • Specify how to generate test code
    • Writing failure case first
    • Writing test cases in natural language first
    • Test only what is necessary
  • Refactoring
    • Writing test code before refactoring
    • Making the calculation part independent
    • Asking with open-ended questions
  • Archived
    • GitHub Copilot Patterns & Exercises Guide
    • Translations
      • German 🇩🇪
      • Spanish 🇪🇸
      • French 🇫🇷
      • Italy 🇮🇹
      • Japanese 🇯🇵
      • Portuguese 🇵🇹
      • Chinese 🇨🇳
Powered by GitBook
On this page
  • Description
  • Example
  • Exercise
  • Checklist for Further Learning
Edit on GitHub
  1. Refactoring

Writing test code before refactoring

GitHub Copilot makes it incrediblly easy to modify code, but the suggested code is not always correct even if it looks good. Writing tests is very important before refactoring it. This is no different

Last updated 1 year ago

Description

In the modern world of software development, refactoring can be seen as a fun and engaging task, especially with tools like GitHub Copilot at your disposal. It's so easy to dive in and make changes, but without proper tests, even the most promising code modification can lead to unexpected results. This pattern emphasizes the importance of writing tests before refactoring code to ensure that the functionality remains consistent. Think of tests as your safety net; they catch the problems before they become catastrophic.

Example

Suppose you have a function that calculates the total price of a shopping cart, and you want to refactor it for better clarity. Here's the original code:

def total_price(items):
    return sum(item['price'] * item['quantity'] for item in items)

Before refactoring, write tests to ensure that the existing functionality is preserved:

def test_total_price():
    items = [
        {'price': 5, 'quantity': 2},
        {'price': 3, 'quantity': 1}
    ]
    assert total_price(items) == 13

Now you can refactor the code to make it more readable:

def total_price(items):
    total = 0
    for item in items:
        total += item['price'] * item['quantity']
    return total

The test still passes, ensuring that your refactoring didn't change the expected outcome.

Exercise

  • Exercise 1: Write a function that needs refactoring and then write corresponding tests for it.

  • Exercise 2: Refactor the function while ensuring that the tests still pass.

  • Exercise 3: Simulate a failure by making an incorrect change in the refactored function and observe how the test helps in catching the error.

Checklist for Further Learning

  • How can you make sure that your tests are covering all the important aspects of the code?

  • What tools and frameworks are available in your language of choice to help write and run tests?

  • How can the practice of Test-Driven Development (TDD) be applied when refactoring? How does it differ from writing tests after the code is written?

  • What are the best practices for organizing your tests? How can they be maintained and updated as the code evolves?