Skip to content

Tests: jobs status and inner logic#186

Open
nm727 wants to merge 4 commits intoColibrITD-SAS:devfrom
nm727:fix-tests-execution
Open

Tests: jobs status and inner logic#186
nm727 wants to merge 4 commits intoColibrITD-SAS:devfrom
nm727:fix-tests-execution

Conversation

@nm727
Copy link

@nm727 nm727 commented Feb 16, 2026

No description provided.

@nm727 nm727 mentioned this pull request Feb 16, 2026
Comment on lines +34 to +44
class TestJobStatus:
def test_all_statuses_exist(self):
expected = {"INIT", "QUEUED", "RUNNING", "CANCELLED", "ERROR", "DONE"}
actual = {s.name for s in JobStatus}
assert expected == actual

def test_terminal_statuses(self):
"""DONE, ERROR, CANCELLED should be considered terminal."""
terminal = {JobStatus.DONE, JobStatus.ERROR, JobStatus.CANCELLED}
non_terminal = {JobStatus.INIT, JobStatus.QUEUED, JobStatus.RUNNING}
assert terminal.isdisjoint(non_terminal)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unsure about the usefulness of these tests

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we can remove the tests, no need.

job = Job(JobType.SAMPLE, circuit, IBMDevice.AER_SIMULATOR, measure)
assert job.measure is not None
# measure should be deep-copied
assert job.measure is not measure
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it

circuit = QCircuit(2)
job = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR)
job.status = JobStatus.DONE
# Should not raise — no remote lookup attempted for local device
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the mentioned feature is not tested IMO

Comment on lines +119 to +122
circuit = QCircuit(2)
job = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR)
job.status = JobStatus.RUNNING
assert job._status == JobStatus.RUNNING
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a super fan of testing setters and init unless they have complex behavior. It adds testing time, makes the overall architecture harder to change, and doesn't really add useful securities to the testing suite

Copy link
Collaborator

@MoHermes MoHermes Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree here we avoid asserting private/internal fields in tests

Comment on lines +133 to +140
def test_terminal_status_no_remote_check(self):
"""Once a job reaches a terminal state, the status property should
return immediately for any device."""
circuit = QCircuit(2)
job = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR)
for terminal in [JobStatus.DONE, JobStatus.ERROR, JobStatus.CANCELLED]:
job.status = terminal
assert job.status == terminal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same ?

Comment on lines +148 to +180
class TestJobEquality:
def test_equal_jobs(self):
circuit = QCircuit([H(0), CNOT(0, 1)])
job1 = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR)
job2 = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR)
assert job1 == job2

def test_different_type(self):
circuit = QCircuit([H(0)])
measure = BasisMeasure([0], shots=100)
job1 = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR)
job2 = Job(JobType.SAMPLE, circuit, IBMDevice.AER_SIMULATOR, measure)
assert job1 != job2

def test_different_device(self):
circuit = QCircuit([H(0)])
job1 = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR)
job2 = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR_STATEVECTOR)
assert job1 != job2

def test_different_circuit(self):
circ1 = QCircuit([H(0)])
circ2 = QCircuit([X(0)])
job1 = Job(JobType.STATE_VECTOR, circ1, IBMDevice.AER_SIMULATOR)
job2 = Job(JobType.STATE_VECTOR, circ2, IBMDevice.AER_SIMULATOR)
assert job1 != job2

def test_not_equal_to_non_job(self):
circuit = QCircuit(2)
job = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR)
assert job != "not a job"
assert job != 42
assert job != None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can use a pytest.mark.parametrize for these tests ?

Comment on lines +189 to +214
def test_repr_no_measure(self):
circuit = QCircuit(2)
job = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR)
r = repr(job)
assert "Job(" in r
assert "STATE_VECTOR" in r
assert "AER_SIMULATOR" in r

def test_repr_with_measure(self):
circuit = QCircuit([H(0)])
measure = BasisMeasure([0], shots=100)
job = Job(JobType.SAMPLE, circuit, IBMDevice.AER_SIMULATOR, measure)
r = repr(job)
assert "BasisMeasure" in r

def test_to_dict_keys(self):
circuit = QCircuit(2)
job = Job(JobType.STATE_VECTOR, circuit, IBMDevice.AER_SIMULATOR)
d = job.to_dict()
assert "job_type" in d
assert "circuit" in d
assert "device" in d
assert "measure" in d
assert "id" in d
assert "status" in d

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these tests look weird to me, why not testing the whole repr at this point ?

circuit = QCircuit([Rx(theta, 0)])
job = generate_job(circuit, IBMDevice.AER_SIMULATOR, {theta: 1.5})
# After substitution the circuit should have no free variables
assert len(job.circuit.variables()) == 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I like what you did, but I think the important thing to test in this file is mostly the remote thing, we can merge this once you reply to/take into account the comments, but the biggest issue remains :(

Also, a general question: what are the classes for ? I never used them so I'm curious :)

@nm727
Copy link
Author

nm727 commented Feb 17, 2026

@Henri-ColibrITD Thank you for the thorough review! I addressed most of your concerns in this commit and attempted at the remote tests.

As for the test classes, they are mainly for grouping, pytest uses them to namespace the -v output, so instead of seeing:

test_local_device_never_polls PASSED
test_no_measurement_gives_state_vector PASSED

you see:

TestRemoteStatus::test_local_device_never_polls PASSED
TestGenerateJob::test_no_measurement_gives_state_vector PASSED

It makes it easier to see which area failed when scanning test output. Totally optional, just a small structural choice to keep things organized as the suite grows

@Henri-ColibrITD Henri-ColibrITD changed the title Add tests execution Tests: jobs status and inner logic Feb 18, 2026
Comment on lines +71 to +81
def test_construction_with_different_devices(self):
circuit = QCircuit(2)
devices = [
IBMDevice.AER_SIMULATOR,
ATOSDevice.MYQLM_PYLINALG,
AWSDevice.BRAKET_LOCAL_SIMULATOR,
GOOGLEDevice.CIRQ_LOCAL_SIMULATOR,
]
for device in devices:
job = Job(JobType.STATE_VECTOR, circuit, device)
assert job.device == device
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this test, just looping through devices to assert job.device is device

Comment on lines +32 to +35
def test_all_types_exist(self):
expected = {"STATE_VECTOR", "SAMPLE", "OBSERVABLE"}
actual = {t.name for t in JobType}
assert expected == actual
Copy link
Collaborator

@MoHermes MoHermes Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this one, doesn't test behaviour

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants