Combined with Test-Driven Development (TDD) methodologies, prompt engineering significantly enhances developers’ work, providing a more agile and efficient development experience.
By mastering prompt engineering, technology professionals can fully harness the potential of tools like StackSpot AI, which understands commands and adapts to individual styles. Clear and precise commands ensure even better results.
In this article, we’ll explore the collaboration between generative artificial intelligence and software development, focusing on unit tests as prompts for code generation. Through a practical example, we’ll demonstrate how StackSpot AI can optimize the development process and ensure software quality using methodologies such as Test-Driven Development (TDD).
What is Test Driven Development (TDD)?
Large-scale software projects require meticulousness and precision. Test-Driven Development (TDD) is a methodology that elevates code quality and fosters technical excellence.
Test-Driven Development tests are written before actual implementation, serving as a blueprint for development and making sure the code is always in line with requirements. This approach strengthens team confidence, speeds up development, and facilitates collaboration.
Teams that embrace Test-Driven Development make the software more robust, easier to maintain, and remarkably reliable. By guaranteeing superior code quality, TDD enhances user satisfaction and ensures a stable user experience.
Benefits of Test-Driven Development (TDD)
There are many benefits to adopting Test-Driven Development (TDD) in software development, such as:
- Superior code quality: By writing the tests first, the developer focuses on creating code that meets the specific requirements of the tests, resulting in cleaner code;
- Improved architecture: Test-Driven Development (TDD) encourages the creation of a modular and testable design, making code maintenance and refactoring simpler and safer;
- Living documentation: Tests serve as executable documentation of the code’s expected behavior, making it easier to understand and modify the system in the future;
- Increased confidence: By having a comprehensive test suite, developers can make changes to the code with more confidence, knowing that the tests will identify any regressions;
- Code that always works: The fail-pass-refactoring cycle ensures that the code is almost always working and easier to debug.
Tests as a prompt
StackSpot AI enables unit tests to replace the need for translating complex ideas into ambiguous natural language. By providing a test, the developer communicates to the AI precisely the expected behavior of a function or class.
This approach is similar to providing an architectural professional with a technical drawing that specifies exactly how the building should look like.
With StackSpot AI, communication between developer and machine becomes more direct and efficient through prompt engineering, resulting in a more agile and accurate development process.
A practical example
Now that we know the advantages of Test-Driven Development (TDD), it’s time to see how StackSpot AI can help in this process.
The problem
For this demonstration, we’ll create a unit test file in Python. This file will be the input that StackSpot AI uses to generate the code.
Problem: I’d like a class that encapsulates a number and makes the bidirectional conversion between the representations in Arabic numbers and Roman characters.
This is the test code:
import unittest
class RomanNumeralTest(unittest.TestCase):
def test_should_create_roman_numeral_object_from_int(self):
actual_numerals = [RomanNumeral(i).as_roman() for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,200, 300, 400,500, 600, 700, 800, 900, 1000]]
expected_numerals = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XX","XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "C", "CC", "CCC", "CD", "D","DC", "DCC", "DCCC", "DCCCC", "M"]
self.assertListEqual(expected_numerals, actual_numerals)
def test_should_create_roman_numeral_object_from_string(self):
actual_numerals = [RomanNumeral(s).as_arabic() for s in ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "C", "CC", "CCC", "CD", "D","DC", "DCC", "DCCC", "DCCC", "M"]]
expected_numerals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
self.assertListEqual(expected_numerals, actual_numerals)
if __name__ == '__main__':
unittest.main()
Enhancing the test
Let’s request a code smells analysis. To do this, right-click within the code editing area to bring up the context menu. From this menu, go to StackSpot AI. A submenu will appear. Select the option “Is there any code smell in this code?“.
This is the answer:
Based on the code snippet provided, it is not possible to say for sure if there are bugs or code smells because the implementation of the RomanNumeral class is not offered. However, there are some observations and possible problems that can be pointed out:
1. The RomanNumeral class is not imported or defined in the code snippet, which would result in a NameError when trying to instantiate RomanNumeral(i) or RomanNumeral(s).
2. The list of numbers expected for the Roman numeral representation 900 may contain a typo. It is listed as “DCCCC”,” but the correct Roman numeral for 900 is “CM”.”
3. The code does not follow the PEP 8 style guide for Python code, which recommends two blank lines before class definitions.
StackSpot AI suggests the following code, correcting the points raised:
import unittest
# Assuming the RomanNumeral class is defined in roman_numeral.py
from roman_numeral import RomanNumeral
class RomanNumeralTest(unittest.TestCase):
def test_should_create_roman_numeral_object_from_int(self):
actual_numerals = [RomanNumeral(i).as_roman() for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]]
expected_numerals = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "M"] # Corrected "DCCCC" to "CM"
self.assertListEqual(expected_numerals, actual_numerals)
def test_should_create_roman_numeral_object_from_string(self):
actual_numerals = [RomanNumeral(s).as_arabic() for s in ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "M" # Assuming "CM" is the correct representation for 900]]
expected_numerals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000]
self.assertListEqual(expected_numerals, actual_numerals)
if __name__ == '__main__':
unittest.main()
Let’s accept the corrections and move on.
Interestingly, StackSpot AI knows topics that go beyond the scope of software development, such as Roman numerals.
Generating the code
I enter the following prompt:
“Provide an implementation of the RomanNumeral class that makes the tests pass.”
StackSpot AI brought a response:
class RomanNumeral:
def __init__(self, value):
if isinstance(value, int):
self.value = value
elif isinstance(value, str):
self.value = self._from_roman(value)
else:
raise TypeError("Value must be an integer or a string representing a Roman numeral.")
def as_roman(self):
return self._to_roman(self.value)
def as_arabic(self):
return self.value
@staticmethod
def _to_roman(number):
roman_numerals = {1000: 'M', 900: 'CM', 500: 'D', 400: 'CD', 100: 'C', 90: 'XC', 50: 'L', 40: 'XL', 10: 'X', 9: 'IX', 5: 'V', 4: 'IV', 1: 'I'}
result = ""
for value, numeral in sorted(roman_numerals.items(), reverse=True):
while number >= value:
result += numeral
number -= value
return result
@staticmethod
def _from_roman(roman):
roman_numerals = {'M': 1000, 'CM': 900, 'D': 500, 'CD': 400, 'C': 100, 'XC': 90, 'L': 50, 'XL': 40, 'X': 10, 'IX': 9, 'V': 5, 'IV': 4, 'I': 1}
index = 0
number = 0
while index < len(roman):
if (index + 1 < len(roman)) and (roman[index:index+2] in roman_numerals):
number += roman_numerals[roman[index:index+2]]
index += 2
else:
number += roman_numerals[roman[index]]
index += 1
return number
StackSpot also guides placing the code in the file roman_numeral.py. When we run the tests, we get positive results for both.
Conclusion
In the practical example of converting Roman numerals, StackSpot AI proved to be a valuable collaborator by identifying and correcting issues in the test code and generating the expected production code.
This collaboration between human and machine sped up the development process, resulting in cleaner, more efficient, and reliable code.
StackSpot AI’s ability to generate high-quality code based on unit tests opens new possibilities for software development in the future.
Check out the StackSpot AI documentation here.
Do you have any questions or suggestions? Please leave a comment.