Skip to content

dscpsyl/jgrade2

 
 

Repository files navigation

Contributors Forks Stargazers Issues MIT License LinkedIn

jGrade2

An annotation library used to help autograde student assignments in Java for Gradescope.
Explore the docs »

Report Bug · Request Feature

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Contributing
  5. License
  6. Acknowledgments

About The Project

This is an update to the original jGrade, now supporting Java17 and JUnit5. This provides four annotations: @Grade (+ @BeforeGrading and @AfterGrading) and @GradedTest, each meant to help autograde student assignments in Java for the Gradescope autograder. When correctly setup, instructors can simply use JUnit5 to write tests for assignemnts. This library will automatically capture results, and output the correct json format for Gradescope to read.

(back to top)

Getting Started

Prerequisites

jGrade2 requires Java 17 and JUnit5. It is recommended to use Maven to manage dependencies. Additional dependencies are listed in the pom.xml file. For the user's convenience, a jar file is provided containing all the dependencies.

Installation

There are two ways to install jGrade2.

  1. Install directly from GitHub releases. You can download either jar files or build the source code from scratch. If building from source, this project uses maven wrapper to build. Simply run ./mvnw clean package to build the project. Two jar files will be created, both reflected on the releases page.
  2. Add as a dependency directly from Maven Central.
<dependency>
  <groupId>io.github.dscpsyl</groupId>
  <artifactId>jgrade2</artifactId>
  <version>${jGrade2.version}</version>
</dependency>

(back to top)

Usage

Usage is nearly identical to the origional jGrade. jGrade2 comes with a commandline to run the grader manually. This is useful for debugging and testing. After compiling, you can use

java -jar jGrade2.jar -h

for help and options of the commandline. However, a typical usage would be

java -jar jGrade2.jar -c ExampleGrading -o results.json

Test Writting and Grading

You can take a look at the gradescope example in examples/gradescope for a full example.

Tests

Tests are written in jUnit5. The only addition will be the @GradedTest annotation to each test that should be counted in the assignment on gradescope.

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import com.github.dscpsyl.jgrade2.gradedtest.GradedTest;

import static com.github.dscpsyl.jgrade2.gradedtest.HIDDEN;
import static com.github.dscpsyl.jgrade2.gradedtest.VISIBLE;

public class ExampleTest {
    @Test
    @GradedTest(name="Example Test", points=10)
    public void testExample() {
        Assertions.assertTrue(true);
    }

    @Test
    @GradedTest(name="Hidden Test", points=10, visibility=HIDDEN)
    public void testHidden() {
        Assertions.assertTrue(true);
    }

    @Test
    @GradedTest(name="Visible Test", number="4", points=10, visibility=VISIBLE)
    public void testVisible() {
        Assertions.assertTrue(true);
    }

}

The @GradedTest annotation has the following parameters:

  • name - The name of the test. This will be displayed in the Gradescope interface. DEFAUT: "Unnamed test"
  • number - The test number in a string. This will be displayed in the Gradescope interface. DEFAULT: ""
  • points - The number of points this test is worth. DEFAULT: 1.0
  • visibility - The visibility of the test. This can be either VISIBLE or HIDDEN. DEFAULT: VISIBLE

Grading

Grading is done by a simple grading class. This class should be in the same package as the tests. Each method in the grading class that should be considered for grading needs to be annotated with @Grade. The method should take in a single parameter of type Grader. @BeforeGrading and AfterGrading can be used to run code before and after grading respectively. These methods should also take in a single parameter of type Grader.

import com.github.dscpsyl.jgrade2.Grader;
import com.github.dscpsyl.jgrade2.GradedTestResult;

import com.github.dscpsyl.jgrade2.Grade;
import com.github.dscpsyl.jgrade2.AfterGrading;
import com.github.dscpsyl.jgrade2.BeforeGrading;

import static com.github.dscpsyl.jgrade2.gradedtest.HIDDEN;

public class ExampleGrading {

  /* This function will run before grading starts*/
  @BeforeGrading
  public void beforeGrading(Grader g) {
    System.out.println("Starting grading");
    grader.startTimer();
  }

  /* You can grade a full test class that is in the same package as this class */
  @Grade
  public void gradeTestClass(Grader g) {
    g.runJUnitGradedTests(ExampleTest.class);
  }

  /* If you cannot use jUnit5 or java to grade, you can manually add results */
  @Grade
  public void gradeManually(Grader g) {
    g.addGradedTestResult(new GradedTestResult("Manual Test", "4" , 10.0, HIDDEN));
  }

  /* Grader.startTimer() and Grader.stopTimer() can be used to time the grader */
  @Grade
  public void loopForTime(Grader grader) {
    long startTime = System.currentTimeMillis();
    while (System.currentTimeMillis() - startTime < 1000);
  }

  /* @AfterGrading methods are run after all other methods. */
  @AfterGrading
  public void endGrader(Grader grader) {
    grader.stopTimer();
    System.out.println("Grading finished");
  }

}

Gradescope Setup

There is a full example in examples/gradescope that works on gradescope, and models much of the setup from the original java example Gradescope links to.

It compiles all files in to a created classes/ directory (not tracked). All the scripts will be looking for your classes in this directory.

The lib/ folder contains all jars and library files needed to run your test - for this example just the jGrade2 jar file (optionally a checkstyle jar for the checkstyle grading method). The res/ directory is for resources (like the checkstyle configuration file).

src/ is the main source code of both your grading code and your tests.

test_submissions/ are submissions to test with on Gradescope. These are precompiled for you to test with the grader that is included in the example.

The source has 2 main packages, staff and student. The staff package contains the unit tests, a solution (to debug with) and the code to do the grading. The student package contains studnet skeleton code for studnets to fill in.

While debugging, a makefile is provided for compiling and running. make output will start fresh and run the autograder, pretty-printing the output to the console.

  • setup.sh: Installs correct JDK
  • run_autograder: Main script for the autograder. Copies in submission, compiles, and runs.
  • compile.sh: Compiles all of the source into a classes directory
  • run.sh: Runs JGrade, passing in the GradeHello file, writing output
    • If run with --local then prints output to console, else to the results/results.json file.

To build the Autograder:

Either:

  1. Run ./mvnw clean package to build the jGrade2 jar
  2. Copy the jGrade2 jar to the lib/ folder
  3. Run either ./make_autograder.sh or make autograder which will place it in the zips/ folder.
  4. Upload the autograder to Gradescope.

Or:

  1. Run ./make_autograder_full.sh which will complete the steps above for you, assuming the gradescope files are still in the examples directory. This will put the final zip in the base directory instead of the zips/ folder. If you want to include checkstyle in the grading, please manually add the checkstyle jar to the lib/ folder before running this script.

(back to top)

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

The repository is structured like so:

  • main & master The main branches for publishing to maven central. These should be kept clean and only update with releases. It is also protected and can only be added to via a pull request.
  • dev The development branch. This is where all development should be done and contains pe-releases. It is protected and can only be added to via a pull request.

Other branches are for personal developnment and should only be pulled to the dev branch. Once a release is determined, then a pull request can be made to main or master.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

(back to top)

License

Distributed under the MIT License. See LICENSE.txt for more information.

(back to top)

Acknowledgments

  • This is an update of the original jGrade.
  • Originally developed by dscpsyl and directed by pconrad
  • Maintained by the CMPSC 192 course staff and students at University of California, Santa Barbara

(back to top)

About

An update to the original jGrade for Java 17 and jUnit 5

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 99.2%
  • Shell 0.8%