You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mooc.fi Java for循环本地运行正常 TMC测试报NoSuchElementException

Mooc.fi Java 练习问题排查

任务要求

  • 第一部分:编写程序,打印从1到用户输入指定数值之间的所有整数
  • 第二部分:新增功能,支持用户输入循环起始数值,打印起始值到终止值区间内的所有整数

问题现象

代码在本地终端手动交互运行时输出符合预期,但提交到TMC平台后WhereFromTest测试用例执行失败,报错信息为:

FAIL: WhereFromTest test NoSuchElementException: No line found

原始问题代码

import java.util.Scanner;

import javax.swing.plaf.synth.SynthOptionPaneUI;

public class FromWhereToWhere {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // part one

        System.out.println("Where to?");
        int end = Integer.valueOf(scanner.nextLine());
        for (int i = 1; i < end + 1; i++) {
            System.out.println(i);
        }

        // part two
        System.out.println("Where to?");
        end = Integer.valueOf(scanner.nextLine());
        System.out.println("Where from?");
        int start = Integer.valueOf(scanner.nextLine());

        for (int i = start; i < end + 1; i++) {
            System.out.println(i);
        }
    }

}

TMC平台对应测试代码

import fi.helsinki.cs.tmc.edutestutils.MockStdio;
import fi.helsinki.cs.tmc.edutestutils.Points;
import fi.helsinki.cs.tmc.edutestutils.ReflectionUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.*;
import static org.junit.Assert.*;

@Points("02-16.2")
public class WhereFromTest {

    @Rule
    public MockStdio io = new MockStdio();

    @Test
    public void test() {
        int[][] pairs = {{1, 1}, {12, 8}, {50, 100}, {-2,2}};
        for (int[] pair : pairs) {
            test(pair);
        }
    }

    private void test(int[] pair) {
        io.setSysIn(pair[0] + "\n" + pair[1] + "\n");
        int len = io.getSysOut().length();

        ReflectionUtils.newInstanceOfClass(FromWhereToWhere.class);
        FromWhereToWhere.main(new String[0]);
        String output = io.getSysOut().substring(len);

        output = output.replaceAll("[^-\\d]+", " ").trim();
        String[] lines = output.split("\\s+");
        int linesInOutput = (lines.length == 1 && lines[0].isEmpty()) ? 0 : lines.length;

        int linesCount;
        if(pair[0] < pair[1]) {
            linesCount = 0;
        } else {
            linesCount = pair[0]  - pair[1] + 1;
        }

        if (linesCount != linesInOutput) {
            String numbersCount = (linesCount == 1) ? "number": "numbers";
            fail("With the input " + pair[0] + ", " + pair[1] + " output should contain " + linesCount + " " + numbersCount + ", now it contained " + linesInOutput);
        }
        
        if(linesCount == 0) {
            return;
        }

        int firstNumber = Integer.valueOf(lines[0]);
        if(firstNumber != pair[1]) {
            fail("With the input " + pair[0] + ", " + pair[1] + " the first printed number should be " + pair[1] + ", now it was " + firstNumber);
        }
        
        int lastNumber = getLastNumber(output);
        if(lastNumber != pair[0]) {
            fail("With the input " + pair[0] + ", " + pair[1] + " the last printed number should be " + pair[0] + ", now it was " + lastNumber);
        }
    }
    
    private static int getLastNumber(String inputStr) {
        String patternStr = "(?s).*?(-?\\d+)\\s*$";
        Matcher matcher = Pattern.compile(patternStr).matcher(inputStr);
        assertTrue("The output should be a number.", matcher.find());

        int number = Integer.valueOf(matcher.group(1));
        return number;
    }
}

报错根因

  • 测试用例针对第二部分功能设计,仅向程序模拟输入2行内容:第一行是区间终止值,第二行是区间起始值,对应程序仅需要读取2次用户输入。本地手动运行时用户可以按需输入足够行数的内容,因此不会触发报错,但自动化测试仅提供固定行数的模拟输入,就会触发读入失败。
  • 原始代码保留了第一部分的完整逻辑,程序启动后会先读取1次输入用于第一部分固定从1开始的打印逻辑,之后第二部分还需要读取2次输入(终止值、起始值),总共需要3行输入。
  • 模拟输入仅提供2行内容,代码尝试读取第三行不存在的输入时,就会抛出NoSuchElementException: No line found错误。
  • 原始代码中存在无用导入javax.swing.plaf.synth.SynthOptionPaneUI,不影响运行但属于冗余代码。

修复方案

  1. 删除第一部分的冗余逻辑,程序启动后直接按第二部分要求交互:先提示输入终止值,读取后再提示输入起始值,最后打印区间内所有整数,保证程序总共仅读取2次输入,和测试的输入设计匹配。
  2. 删除无用的Swing相关导入语句。
  3. 保留原有循环判断逻辑:当起始值大于终止值时循环不执行,不输出任何内容,和测试用例的校验规则一致。

修复后的可通过测试的代码如下:

import java.util.Scanner;

public class FromWhereToWhere {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("Where to?");
        int end = Integer.valueOf(scanner.nextLine());
        System.out.println("Where from?");
        int start = Integer.valueOf(scanner.nextLine());

        for (int i = start; i <= end; i++) {
            System.out.println(i);
        }
    }
}

注:循环判断条件i < end + 1和i <= end逻辑完全等价,后者可读性更好。

内容的提问来源于stack exchange,提问作者SkyCowie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 02:24:34