1
\$\begingroup\$

I'm implementing genetic algorithm in Java and I want to learn TDD with this project.

Currently I have this code:

package geneticAlgoritm;

import geneticAlgoritm.randomNumbers.IRandomGenerator;
import geneticAlgoritm.randomNumbers.RandomGenerator;
import lombok.Getter;
import lombok.NonNull;

import java.util.List; 

public class Population {
    @NonNull private IRandomGenerator generator = new RandomGenerator();

    @Getter
    @NonNull
    private List<Chromosome> population;

    @NonNull final IFitnessCalculator calculator;

    public Population(int n, IFitnessCalculator calculator) {
        this.calculator = calculator;
        this.population = generatePopulation(n);
    }

    int nextGeneration() {

    }

    private List<Chromosome> generatePopulation(int n) {
        return null;
    }

    private Chromosome mutate(Chromosome chromosome, double probability) {
        return null;
    }

    private Chromosome crossover(Chromosome first, Chromosome second, double probability) {
        return null;
    }

    private List<Chromosome> pickBestOfPopulation(int n) {
        return null;
    }
}

Basically, I have Chromosome class, which is wrapper for byte[] array and fitness of that array.

nextGeneration generates new population with better traits. How I can change design to allow testing crossover, mutate etc functions?

nextGeneration is really inconvenient to test for all functionalities, especially with some randomness in each (I'm using custom interface to remove it).

\$\endgroup\$
  • \$\begingroup\$ "IRandomGenerator" generator should be passed in the constructor. Add the test class with some cases. Right now, I don't know what nextGeneration will do. That's a good way to start with TDD. \$\endgroup\$ – A Bravo Dev Jan 3 '18 at 22:42
1
\$\begingroup\$

You have already written the API of your implementation. Being strict: That's not how tdd works.

  1. Write one failing test
  2. Make the test pass
  3. Refactor

Your test case should not only test your implementation, but also document the behaviour of your implementation - without having written the implementation. And if you're at the first point, your test case describes the expected behaviour of your implementation. And it guides the design of your implementation.

And what's very important, too: Know when to stop. If you have code which is not covered by your test cases - and should be covered by a test case - at the end of an iteration, you did it wrong.

And in my opinion: A code review does help, but not too much. Because with tdd, an application grows iteration by iteration. And the thoughts which have to be thought during those steps have to be learned and practiced.

\$\endgroup\$
  • \$\begingroup\$ @Jump3r It's possible the confusion was between the terms "TDD" and "Unit testing". These are related concepts but not synonymous \$\endgroup\$ – Ben Aaronson Jan 4 '18 at 18:40
  • \$\begingroup\$ I was just thinking about this concept as: 1. create needed methods stubs, 2. create tests to make specify behaviour, 3. implement to pass tests. \$\endgroup\$ – Jump3r Jan 4 '18 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.