简体   繁体   中英

How to automation testing with a Console Application with already test cases set

I just complete a Java CONSOLE application for Student Management.

I received a test case set (pdf file contains lines follow according to the requirements of the application) build based on the standard program (from my lecturer) . You can overview what my app do and what is format of test casenter image description heree set in the attached image below.

The problem is that I want to use test cases for testing my app but instead of manually entering and matching line by line between Console IO and the pdf file => I want to write a program to automatically import and match the data between my jar/program to test cases .

However, I'm not sure how and where to start. I have tried with google but unit test/white testing is still the thing that takes up all of my search. Hopefully in the process of continuing to try to search with google, someone will give me some suggestions or directions that will be useful to me. Thanks very much.

[My Program]

[Test cases set]

The way I'd do it is to decouple your application from the console so that you can use fake implementations for printing and reading from the console in your tests. "Fake" is the technical term - you can look up "test doubles" to learn about those and other related ideas. This idea is known as dependency injection, or the dependency inversion principle.

The way we do this is to use interfaces. Here's an example of an application that prints some items:

import java.util.List;

public class ItemPrinterApplication {
    public ItemPrinterApplication(OutputWriter outputWriter, List<Item> items) {
        this.outputWriter = outputWriter;
        this.items = items;
    }

    public void run() {
            outputWriter.writeLine("Name, Price");
            items.forEach(item -> outputWriter.writeLine(item.name + ", " + item.price));
    }

    private OutputWriter outputWriter;
    private List<Item> items;
}

OutputWriter is the thing responsible for the printing. It's just an interface, so the application doesn't know whether it writes to the console or somewhere else:

public interface OutputWriter {
    void writeLine(String line);
}

For completeness, the Item class just holds some data:

public class Item {
    public Item(String name, Integer price) {
        this.name = name;
        this.price = price;
    }

    public final String name;
    public final Integer price;
}

I can then write a test using JUnit that checks that when I run this application, I get the output that I want. I do that by using an implementation of OutputWriter that just writes to a string. That way it's easy to check in the test:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.List;

public class ItemPrinterTest {
    @Test
    public void itPrintsAListOfItems() {
        List<Item> items =
                List.of(
                        new Item("Apple", 50),
                        new Item("Carrot", 25),
                        new Item("Milk", 120)
                );

        FakeOutputWriter fakeOutputWriter = new FakeOutputWriter();
        ItemPrinterApplication app = new ItemPrinterApplication(fakeOutputWriter, items);

        app.run();

        Assertions.assertEquals(
                "Name, Price\n" +
                        "Apple, 50\n" +
                        "Carrot, 25\n" +
                        "Milk, 120\n",
                fakeOutputWriter.written
        );
    }
}

and FakeOutputWriter looks like

public class FakeOutputWriter implements OutputWriter {
    public String written = "";

    @Override
    public void writeLine(String line) {
        written += line;
        written += "\n";
    }
}

This gives me confidence that I'm writing the output correctly. In main , though, I want to actually print to the console:

import java.util.List;

public class Main {
    public static void main(String[] args) {
        OutputWriter outputWriter = new ConsoleOutputWriter();
        List<Item> items =
                List.of(
                        new Item("Apple", 50),
                        new Item("Carrot", 25),
                        new Item("Milk", 120)
                );

        new ItemPrinterApplication(outputWriter, items).run();
    }
}

and ConsoleOutputWriter does exactly that:

public class ConsoleOutputWriter implements OutputWriter{
    @Override
    public void writeLine(String line) {
        System.out.println(line);
    }
}

You could take the same approach for faking reading input. Your interface would have a function that takes no arguments and reads a string:

interface InputReader {
    String readLine()
}

so in the tests you could fake that and in main , read using a Scanner or something.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM