Skip to main content

A check50 extension for java

Project description

check50_java

This is an extension, a collection of utility scripts, for the CS50 automarker check50.

It provides convenient wrappers around check50.run, for compiling and interpreting Java source/byte code. It also comes with functions to execute and interpret the results of [Junit5][junit] unit tests.

Example Usage

All examples below assume that you're importing check50 and check50_java.

Compile Java source code

@check50.check()
def someclass_compiles():
    check50_java.compile("SomeClass.java"
        classpaths=['your/classpaths',
                    'relative/to/the',
                    'pset/directory.jar']
    )

The classpaths argument defaults to None ~ '.'.

Check that a class is executable (has well-formed main method)

@check50.check(someclass_compiles)
def someclass_main_exists():
    """SomeClass is application class"""
    check50_java.checks.is_application_class("SomeClass")

Execute an application class and check that its output is as expected

@check50.check(someclass_main_exists)
def someclass_main_output():
    """SomeClass.main() output"""
    expected = "X"
    actual = check50_java.run("SomeClass").stdout()
    help_msg = "did you introduce training newline or whitespace characters?"
    if actual != expected:
        raise check50.Mismatch(expected, actual, help=help_msg)

Turning Junit tests into check50 checks

This module ships with Junit5's stand-alone console launcher, which can be used to compile and run unit checks. What seems to work quite well is to add compiled java bytecode for junit test classes to the pset, and run them during checks. The resulting XML report file will reflect things like undefined classes or when method signatures in student code are incompatible with the model solution against which the unit tests were compiled. A full example follows.

  1. Write your model solution and unit test classes and manually compile them.

    public class Drink {
        private final int volume;
    
        public Drink(int v) {
            volume = v;
        }
    
        int getVolume() {
            return volume;
        }
    
    import static org.junit.jupiter.api.Assertions.*;
    import org.junit.jupiter.api.Test;
    
    class DrinkTest {
      @Test
      public void getVolume() {
        Drink d = new Drink(200);
        assertEquals(200, d.getVolume());
      }
    }
    
  2. Move BasketTest.class somewhere into your pset directory, say under tests/.

  3. Add a check as follows (I would usually have this depend on class exists, compiles, and can be instantiated checks).

    @check50.check()
    def drink_getVolume():
        """Test Drink.getVolume()"""
        check50_java.junit5.run_and_interpret_test(
            classpaths=['tests/'],
            args=['--select-method', 'DrinkTest#getVolume'])
    

This will run the precompiled unit test on the student submission, parse junit's XML report and raise any check50.Failures as appropriate for the result. In this case it would raise a check50.Mismatch exception if the assertEquals within the unit test is thrown.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

check50_java-0.2.tar.gz (2.0 MB view hashes)

Uploaded Source

Built Distribution

check50_java-0.2-py3-none-any.whl (2.0 MB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page