一个JUnit如何测试一个交互式的,基于文本的Java应用程序?

ProfPlum

理想情况下,我想编写JUnit测试代码,以交互方式测试学生基于文本的I / O应用程序。使用System.setIn()/.setOut()会导致问题,因为基础流正在阻塞。在较早的帖子(基于测试控制台的应用程序/程序-Java)中建议使用Birkner的系统规则(http://www.stefan-birkner.de/system-rules/index.html,但它似乎要求所有标准输入必须在单元测试目标运行之前提供,因此不能交互。

为了提供具体的测试目标示例,请考虑以下猜测游戏代码:

public static void guessingGame() {
    Scanner scanner = new Scanner(System.in);
    Random random = new Random();
    int secret = random.nextInt(100) + 1;
    System.out.println("I'm thinking of a number from 1 to 100.");
    int guess = 0;
    while (guess != secret) {
        System.out.print("Your guess? ");
        guess = scanner.nextInt();
        final String[] responses = {"Higher.", "Correct!", "Lower."};
        System.out.println(responses[1 + new Integer(guess).compareTo(secret)]);
    }
}

现在想象一下一个JUnit测试,它将提供猜测,读取响应以及玩游戏直至完成。在JUnit测试框架中如何做到这一点?

回答:

使用以下安德鲁·查涅斯基(Andrew Charneski)推荐的方法,添加输出刷新(包括System.out.flush();在上述每个打印语句之后添加),非随机播放以及System.in/out的恢复,此代码似乎执行了我想象中的测试:

@Test
public void guessingGameTest() {
    final InputStream consoleInput = System.in;
    final PrintStream consoleOutput = System.out;
    try {
        final PipedOutputStream testInput = new PipedOutputStream();
        final PipedOutputStream out = new PipedOutputStream();
        final PipedInputStream testOutput = new PipedInputStream(out);
        System.setIn(new PipedInputStream(testInput));
        System.setOut(new PrintStream(out));
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    PrintStream testPrint = new PrintStream(testInput);
                    BufferedReader testReader = new BufferedReader(
                            new InputStreamReader(testOutput));
                    assertEquals("I'm thinking of a number from 1 to 100.", testReader.readLine());
                    int low = 1, high = 100;
                    while (true) {
                        if (low > high)
                            fail(String.format("guessingGame: Feedback indicates a secret number > %d and < %d.", low, high));
                        int mid = (low + high) / 2;
                        testPrint.println(mid);
                        testPrint.flush();
                        System.err.println(mid);
                        String feedback = testReader.readLine();
                        if (feedback.equals("Your guess? Higher."))
                            low = mid + 1;
                        else if (feedback.equals("Your guess? Lower."))
                            high = mid - 1;
                        else if (feedback.equals("Your guess? Correct!"))
                            break;
                        else
                            fail("Unrecognized feedback: " + feedback);
                    }
                } catch (IOException e) {
                    e.printStackTrace(consoleOutput);
                } 
            }
        }).start();
        Sample.guessingGame();
    }
    catch (IOException e) {
        e.printStackTrace();
        fail(e.getMessage());
    }
    System.setIn(consoleInput);
    System.setOut(consoleOutput);
}
安德鲁·查内斯基(Andrew Charneski)

使用PipedInput / OutputStream,例如

    final PrintStream consoleOutput = System.out;
    final PipedOutputStream testInput = new PipedOutputStream();
    final PipedOutputStream out = new PipedOutputStream();
    final PipedInputStream testOutput = new PipedInputStream(out);
    System.setIn(new PipedInputStream(testInput));
    System.setOut(new PrintStream(out));
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                PrintStream testPrint = new PrintStream(testInput);
                BufferedReader testReader = new BufferedReader(
                    new InputStreamReader(testOutput));
                while (true) {
                    testPrint.println((int) (Math.random() * 100));
                    consoleOutput.println(testReader.readLine());
                }
            } catch (IOException e) {
                e.printStackTrace(consoleOutput);
            }
        }
    }).start();
    guessingGame();

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

一个JUnit如何测试一个交互式的,基于文本的Java应用程序?

来自分类Dev

启动一个非交互式的基于Spring-Shell的应用程序

来自分类Dev

创建一个交互式事件调度程序

来自分类Dev

从另一个程序交互式调试python代码

来自分类Dev

如何让一个应用程序与内部网中的服务器交互?

来自分类Dev

如何获得bash脚本来响应另一个交互式脚本?

来自分类Dev

如何获得另一个非root用户的交互式shell?

来自分类Dev

SQL:如何在一个查询(插入行)中编写多个交互式脚本

来自分类Dev

如何获得另一个非root用户的交互式shell?

来自分类Dev

如何以另一个用户身份运行交互式命令

来自分类Dev

如何使用wxPython构造一个交互式对话框?

来自分类Dev

如何为find返回的每个目录生成一个交互式shell?

来自分类Dev

如何在一个终端上使用多个交互式作业而不停止它们?

来自分类Dev

量角器和角度:如何在一个应用程序中一个接一个地测试两个页面?

来自分类Dev

量角器和角度:如何在一个应用程序中一个接一个地测试两个页面?

来自分类Dev

如何在 IntelliJ 中运行一个新的基于 Maven 的“快速入门”应用程序?

来自分类Dev

如何基于另一个值启用/禁用交互式网格报告中的 HTML 表达式按钮

来自分类Dev

如何占用内存来测试另一个应用程序?

来自分类Dev

如何使用现有应用程序的spring配置类仅测试一个bean?

来自分类Dev

如何使用现有应用程序的spring配置类仅测试一个bean?

来自分类Dev

如何从一个文本文件读取然后在一个控制台应用程序中写入另一个文件?

来自分类Dev

单击一个应用程序

来自分类Dev

交互式绘图无法使用从另一个程序通过管道传递的输入进行初始化

来自分类Dev

如何使用SendKeys语句将文本插入另一个应用程序

来自分类Dev

如何在iOS的另一个应用程序中设置文本

来自分类Dev

我应该如何在应用程序的多个页面上显示一个文本块?

来自分类Dev

如何检测或监控另一个 Android 应用程序中的触摸编辑文本?

来自分类Dev

我如何给一个反应应用程序间隔

来自分类Dev

如何与TightVNC共享一个应用程序窗口?

Related 相关文章

  1. 1

    一个JUnit如何测试一个交互式的,基于文本的Java应用程序?

  2. 2

    启动一个非交互式的基于Spring-Shell的应用程序

  3. 3

    创建一个交互式事件调度程序

  4. 4

    从另一个程序交互式调试python代码

  5. 5

    如何让一个应用程序与内部网中的服务器交互?

  6. 6

    如何获得bash脚本来响应另一个交互式脚本?

  7. 7

    如何获得另一个非root用户的交互式shell?

  8. 8

    SQL:如何在一个查询(插入行)中编写多个交互式脚本

  9. 9

    如何获得另一个非root用户的交互式shell?

  10. 10

    如何以另一个用户身份运行交互式命令

  11. 11

    如何使用wxPython构造一个交互式对话框?

  12. 12

    如何为find返回的每个目录生成一个交互式shell?

  13. 13

    如何在一个终端上使用多个交互式作业而不停止它们?

  14. 14

    量角器和角度:如何在一个应用程序中一个接一个地测试两个页面?

  15. 15

    量角器和角度:如何在一个应用程序中一个接一个地测试两个页面?

  16. 16

    如何在 IntelliJ 中运行一个新的基于 Maven 的“快速入门”应用程序?

  17. 17

    如何基于另一个值启用/禁用交互式网格报告中的 HTML 表达式按钮

  18. 18

    如何占用内存来测试另一个应用程序?

  19. 19

    如何使用现有应用程序的spring配置类仅测试一个bean?

  20. 20

    如何使用现有应用程序的spring配置类仅测试一个bean?

  21. 21

    如何从一个文本文件读取然后在一个控制台应用程序中写入另一个文件?

  22. 22

    单击一个应用程序

  23. 23

    交互式绘图无法使用从另一个程序通过管道传递的输入进行初始化

  24. 24

    如何使用SendKeys语句将文本插入另一个应用程序

  25. 25

    如何在iOS的另一个应用程序中设置文本

  26. 26

    我应该如何在应用程序的多个页面上显示一个文本块?

  27. 27

    如何检测或监控另一个 Android 应用程序中的触摸编辑文本?

  28. 28

    我如何给一个反应应用程序间隔

  29. 29

    如何与TightVNC共享一个应用程序窗口?

热门标签

归档