Test tools for the Go solutions of the problems from "Elements of Programming Interview"
EPI Judge Golang is a tool that attempts to offer for Go what the original EPI Judge offers for C++, Java and Python:
- stub programs
- test cases
These allow to validate that a solution (implemented in Go) to one of the EPI problem passes all the tests included in the original EPI Judge.
EPI stands for "Elements of Programming Interview", a book with algorithmic problems and solutions, a great tool for anyone preparing for programming interviews, learning algorithms or just enjoying tricky programming challenge. If you don't know it, check it out here. The authors of the book also offer a free online tool for testing your solution called EPI Judge.
The original book series don't cover Go, and the original EPI Judge doesn't offer a framework for solving problems and testing the solutions in Go. This is where this repository comes in, offering a Golang version of the EPI Judge.
Clone or fork this repository:
git clone https://github.com/stefantds/go-epi-judge
Clone the original EPI Judge repository. The EPI Judge Golang uses the tests cases defined in tsv files in the original EPI Judge repository. These files are not duplicated in this repository but are needed for running the tests.
git clone https://github.com/adnanaziz/EPIJudge
In the go-epi-judge
local repository, create a config file by duplicating config.example.yml
and call it config.yml
cd ./go-epi-judge
cp config.example.yml config.yml
Edit config.yml
to set the testDataFolder
property to the absolute path to the test_data
folder found in the local clone of the original EPI Judge. It should look something like:
testDataFolder: /Users/stefantds/gitrepos/EPIJudge/test_data
All the problems are found in the epi
folder. Each problem can be found by its name. The problem names are exactly the same as in the book and in the original EPI Judge.
Each problem has its own package in a folder in the epi
folder. Each of these folders contain the following:
- a
solution.go
file: here is the method that needs to be implemented. Only this file needs to be modified. - a
solution_test.go
file: it contains the test code that allows to test the solution. - a
main_test.go
file: it also contains test code, it allows to initialize the test. - potentially other files with some types needed by the problem.
Tests can be run in the classical Go way. See https://golang.org/pkg/testing/ for more information on flags and options.
Run all test for a particular problem:
go test ./epi/bst_from_preorder
Run all tests for all problems:
go test ./...
Run one particular test for a particular problem:
go test ./epi/bst_from_preorder -run TestRebuildBSTFromPreorder/Test_Case_0
Multiple solutions for the same problem can be tested (assuming the same function signature). This covers the case where several solution are implemented and all should be tested against the provided test cases. In order to add more functions to the ones to be tested, identify in the corresponding test file the array of solutions at the beginning of the file and add all the functions (or stucts in some cases) that need to be tested.
E.g. (in epi/count_bits/solution_test.go
):
var solutions = []solutionFunc{
CountBits,
CountBitsV2,
}
Running test cases in parallel is supported and can be enabled or disabled by the property runParallelTests
in config.yml
(which enables or disables the call to t.Parallel()
for every test case). Running test cases in parallel can increase the test speed considerably. However, the test cases are then run in a random order which, together with the parallel aspect, can make debugging difficult. Therefore, it can be easily enabled or disabled.
It often makes sense to limit the execution time of tests to a reasonable amount of time. This allows to catch cases like infinite loops or too high complexity algorithms. This can be easily achieved with the default Go testing tools, by using the timeout parameter:
go test ./epi/nonuniform_random_number -timeout 30s
In order to track the progress, a CLI tool is included in this repository. The original EPI Judge has a similar tool (but presented as a HTML page).
Usage: ./progress [options] [chapter_nb ...]
Options:
-d string
path to epi folder. (default "./epi")
-v show detailed test status.
See progress aggregated per chapter (for all chapters):
go run ./progress
See progress aggregated per chapter (for selected chapters):
go run ./progress 8 10
See progress with details (for selected chapters):
go run ./progress -v 8 10
See progress with details (for all chapters):
go run ./progress -v
Note that running the commands from a different repository requires to additionally pass the path to the epi
folder as a parameter.
See help for more details:
go run ./progress -h
The progress tracking is relying on some .progress
files that are being updated when tests are run. However, if the test use cache, the progress files are not updated. In some cases a fresh calculation is desired: just run go test
for all the problems while disabling cache:
go test ./... -count=1
No, it's just "fan art". It's a tool that was intended for personal usage but can be useful to anyone. I'm not associated with or backed by the authors of the original EPI Judge.
No, there are no solutions in this repository, as it is intended as a starting point for anyone who wants to solve the EPI problems in Go. But you can find my solutions at https://github.com/stefantds/go-epi-solutions.
Yes, in the sense that they read the test case files and run the same tests. Also, most of the testing logic follows the test logic from the original EPI Judge. In some cases, small adaptations were made.
I had this aspect in mind when working on this repository, therefore:
- all the problems have exactly the same name as in the original EPI Judge (but use snake case, as it's typical for Go)
- all the solution functions, parameter names and custom type names have the same names as in the original EPI Judge
- most of the function signatures are identical to the ones from the original EPI Judge (there are a few exceptions where it made sense to use some Go features, like multiple return values). This should make it easier to follow the problems and solutions in the book or in the original EPI Judge and solve them in Go with this tool.
If you find an issue know how to fix it, feel free to open a pull request. If you are not sure, we can first discuss the different options in the ticket.
Pull requests are welcome. If it's a feature request, please open an issue first to discuss what you would like to change.