To catch you up, I started my first open source project this fall which is called Scrappy. Scrappy is a command line tool that will convert any website that can be scraped into a markdown. The code base is getting bigger and bigger each commit and its getting harder to manage it. So we decided to start adding unit tests to make sure we are not missing anything before we push commits.
In this commit, I have added the necessary tests that were needed for now. so lets go over what stack I used and why?
Unit test - Jest
Jest is one of the most popular testing frameworks for Javascript. I had prior experience with working with jest, so I decided to use jest for this project. Setting up jest is very very easy, just run npm install --save-dev jest
and add the jest script onto your scripts in package.json with an appropriate command name. And you are done, you can start adding tests with proper name of the files and run your command in your terminal to get the tests running.
Understanding jest is very simple, here is a snippet of one of the tests I made for this commit. Here I am only verifying that passing the -v command in the args in the function validateArgs
should return False. You can see how intuitive it is to use jest. While adding these tests I realized that a branch of my code which uses --api-key flag was broken. Which made me realize how we can get caught up in our new features and might accidentally break our old functionality. Now that I have tests I can rest assured that my changes are backwards compatible.
test('validate args with -v', async () => {
let args = ['node', '/usr/local/bin/scrappy', 'files/input.txt', '-v']
let state = await validateArgs(args)
expect(state).toEqual(false)
})
Testing the LLM capabilities
For testing LLM, we decided to mock the HTTP call to the LLM service to that we can base our tests accordingly. There many libraries to achieve this, but I just hardcoded the http response and mocked it using the jest mock. I decided not to use a framework because my project was small and it was not necessary. Maybe in the future if we are making too many http calls we can think of using a library to imitate a server with the urls we need. I used the mockResolvedValue function offered by jest to make sure I always get the same value when I call the groq LLM function.
test('convert the body into markdown', async () => {
let groq = new Groq({ apiKey: '1234' })
groq.chat = {
completions: {
create: jest.fn().mockResolvedValue(mockGrokResponse)
}
}
let body = 'the body of the webpage'
let md = await getGroqResponse(body, groq)
expect(md).not.toBeNull()
expect(md).toEqual(content)
})
Conclusion
Adding tests made me more confident in my code and more reluctant and worried when others work on my open source project. I also was able to find a bug in one of my branches. This will eventually save time of the future contributors of my project. One of my main conclusion of this process is to add tests at the go and not push it so that its a task in your backlog waiting to be completed. This may pile up and cause issues.
Top comments (0)