Refactor shift constraints in tests to use new constraint classes
- Updated test cases in `test_workers.py` to replace dictionary-based constraints with instances of `PreShiftConstraint`, `PostShiftConstraint`, and `MaxShiftsPerWeekConstraint`. - Added a new test `test_worker_assign_as_block_preference2` to verify worker preferences for block assignments. - Marked tests as slow where appropriate to improve test suite performance.
This commit is contained in:
+60
-32
@@ -1,9 +1,10 @@
|
||||
import pytest
|
||||
from rota.shifts import InvalidShift, NoWorkers, RotaBuilder, SingleShift, WarningTermination, WorkerRequirement, days
|
||||
from rota.shifts import InvalidShift, MaxShiftsPerWeekConstraint, NoWorkers, PostShiftConstraint, RotaBuilder, SingleShift, WarningTermination, WorkerRequirement, days
|
||||
|
||||
import datetime
|
||||
from rota.workers import NonWorkingDays, NotAvailableToWork, Worker, generate_not_available_to_works
|
||||
from rota.workers import WorkRequests
|
||||
from web.rota.shifts import PreShiftConstraint
|
||||
|
||||
def generate_basic_rota(
|
||||
weeks_to_rota=10, workers=0, start_date=datetime.date(2022, 3, 7)
|
||||
@@ -577,9 +578,9 @@ def test_worker_requirement_and_force_block():
|
||||
days=days[:4],
|
||||
workers_required=wr,
|
||||
force_as_block=True,
|
||||
constraint=[
|
||||
{"name": "pre", "options": 2},
|
||||
{"name": "post", "options": 3},
|
||||
constraints=[
|
||||
PreShiftConstraint(days=2),
|
||||
PostShiftConstraint(days=3),
|
||||
]
|
||||
),
|
||||
SingleShift(
|
||||
@@ -589,9 +590,9 @@ def test_worker_requirement_and_force_block():
|
||||
days=days[4:],
|
||||
workers_required=wr,
|
||||
force_as_block=True,
|
||||
constraint=[
|
||||
{"name": "pre", "options": 2},
|
||||
{"name": "post", "options": 3},
|
||||
constraints=[
|
||||
PreShiftConstraint(days=2),
|
||||
PostShiftConstraint(days=3),
|
||||
]
|
||||
),
|
||||
)
|
||||
@@ -606,6 +607,7 @@ def test_worker_requirement_and_force_block():
|
||||
assert shift_string.count("cccc") == shift_string.count("c") / 4
|
||||
assert shift_string.count("ddd") == shift_string.count("d") / 3
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_split_shift():
|
||||
Rota = generate_basic_rota(workers=11, weeks_to_rota=22)
|
||||
|
||||
@@ -620,10 +622,10 @@ def test_split_shift():
|
||||
length=12.5,
|
||||
days=days[:4],
|
||||
workers_required=1,
|
||||
constraint=[
|
||||
{"name": "pre", "options": 2},
|
||||
{"name": "post", "options": 3},
|
||||
{"name": "max_shifts_per_week", "options": 1},
|
||||
constraints=[
|
||||
PreShiftConstraint(days=2),
|
||||
PostShiftConstraint(days=3),
|
||||
MaxShiftsPerWeekConstraint(max_shifts=1),
|
||||
]
|
||||
),
|
||||
SingleShift(
|
||||
@@ -633,9 +635,9 @@ def test_split_shift():
|
||||
days=(days[4], days[6]),
|
||||
workers_required=1,
|
||||
assign_as_block=True,
|
||||
constraint=[
|
||||
{"name": "pre", "options": 2},
|
||||
{"name": "post", "options": 3},
|
||||
constraints=[
|
||||
PreShiftConstraint(days=2),
|
||||
PostShiftConstraint(days=3),
|
||||
]
|
||||
),
|
||||
SingleShift(
|
||||
@@ -644,9 +646,9 @@ def test_split_shift():
|
||||
length=12.5,
|
||||
days=days[5],
|
||||
workers_required=1,
|
||||
constraint=[
|
||||
{"name": "pre", "options": 2},
|
||||
{"name": "post", "options": 3},
|
||||
constraints=[
|
||||
PreShiftConstraint(days=2),
|
||||
PostShiftConstraint(days=3),
|
||||
]
|
||||
),
|
||||
)
|
||||
@@ -685,7 +687,7 @@ def test_locums_basic():
|
||||
days=days[:4],
|
||||
workers_required=1,
|
||||
|
||||
constraint=[
|
||||
constraints=[
|
||||
#{"name": "pre", "options": 1},
|
||||
#{"name": "post", "options": 1},
|
||||
#{"name": "max_shifts_per_week", "options": 1},
|
||||
@@ -734,7 +736,7 @@ def test_locums_nwds():
|
||||
days=days[:4],
|
||||
workers_required=1,
|
||||
|
||||
constraint=[
|
||||
constraints=[
|
||||
#{"name": "pre", "options": 1},
|
||||
#{"name": "post", "options": 1},
|
||||
#{"name": "max_shifts_per_week", "options": 1},
|
||||
@@ -751,7 +753,6 @@ def test_locums_nwds():
|
||||
assert Rota.results.solver.status == "ok"
|
||||
|
||||
for worker in Rota.get_workers():
|
||||
print( Rota.get_worker_shift_list(worker))
|
||||
assert Rota.get_worker_shift_list(worker).count("a") == 4
|
||||
|
||||
if worker.name in ("worker03", "worker04"):
|
||||
@@ -782,7 +783,7 @@ def test_locums_no_availablity():
|
||||
days=days[:4],
|
||||
workers_required=1,
|
||||
|
||||
constraint=[
|
||||
constraints=[
|
||||
#{"name": "pre", "options": 1},
|
||||
#{"name": "post", "options": 1},
|
||||
#{"name": "max_shifts_per_week", "options": 1},
|
||||
@@ -794,6 +795,7 @@ def test_locums_no_availablity():
|
||||
with pytest.raises(WarningTermination):
|
||||
Rota.build_and_solve()
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_locums():
|
||||
Rota = generate_basic_rota(workers=7, weeks_to_rota=10)
|
||||
|
||||
@@ -832,10 +834,10 @@ def test_locums():
|
||||
days=days[:4],
|
||||
workers_required=1,
|
||||
|
||||
constraint=[
|
||||
{"name": "pre", "options": 2},
|
||||
{"name": "post", "options": 3},
|
||||
{"name": "max_shifts_per_week", "options": 1},
|
||||
constraints=[
|
||||
PreShiftConstraint(days=2),
|
||||
PostShiftConstraint(days=3),
|
||||
MaxShiftsPerWeekConstraint(max_shifts=1),
|
||||
]
|
||||
),
|
||||
SingleShift(
|
||||
@@ -845,9 +847,9 @@ def test_locums():
|
||||
days=(days[4], days[6]),
|
||||
workers_required=1,
|
||||
assign_as_block=True,
|
||||
constraint=[
|
||||
{"name": "pre", "options": 2},
|
||||
{"name": "post", "options": 3},
|
||||
constraints=[
|
||||
PreShiftConstraint(days=2),
|
||||
PostShiftConstraint(days=3),
|
||||
]
|
||||
),
|
||||
SingleShift(
|
||||
@@ -856,9 +858,9 @@ def test_locums():
|
||||
length=12.5,
|
||||
days=days[5],
|
||||
workers_required=1,
|
||||
constraint=[
|
||||
{"name": "pre", "options": 2},
|
||||
{"name": "post", "options": 3},
|
||||
constraints=[
|
||||
PreShiftConstraint(days=2),
|
||||
PostShiftConstraint(days=3),
|
||||
]
|
||||
),
|
||||
)
|
||||
@@ -912,11 +914,37 @@ def test_worker_assign_as_block_preference():
|
||||
shift_list_4 = Rota.get_worker_shift_list_string(worker4)
|
||||
assert shift_list_4.count("a") == 12, "Worker 4 should have at least 12 'a' shifts, but may not be grouped together"
|
||||
|
||||
|
||||
def test_worker_assign_as_block_preference2():
|
||||
"""Test that a worker's assign_as_block preference is respected over the global setting."""
|
||||
Rota = generate_basic_rota(workers=4, weeks_to_rota=8)
|
||||
|
||||
# Worker 1 prefers to have shift 'a' assigned as a block, worker 2 does not
|
||||
workers = Rota.get_workers()
|
||||
worker1 = workers[0]
|
||||
worker2 = workers[1]
|
||||
worker3 = workers[2]
|
||||
worker4 = workers[3]
|
||||
|
||||
|
||||
# Add a shift 'a' that is NOT globally set as assign_as_block
|
||||
Rota.add_shifts(
|
||||
SingleShift(
|
||||
sites=("group1",),
|
||||
name="a",
|
||||
length=8,
|
||||
days=days[:4],
|
||||
workers_required=1,
|
||||
assign_as_block=False, # global setting is off
|
||||
),
|
||||
)
|
||||
|
||||
# Modify worker1's preference to prevent block 'a' shifts
|
||||
worker1.assign_as_block_preferences = {"a":-1}
|
||||
Rota.build_and_solve(options={"ratio": 0.0})
|
||||
Rota.export_rota_to_html("test_worker_assign_as_block_preference", folder="tests")
|
||||
shift_list_1 = Rota.get_worker_shift_list_string(worker1)
|
||||
assert shift_list_1.count("aaaa") == 0, "Worker 1 should have all 'a' shifts grouped together (block)"
|
||||
assert shift_list_1.count("aaaa") == 0, "Worker 1 should have less 'a' shifts grouped together (block)"
|
||||
|
||||
worker1.assign_as_block_preferences = {"a":0}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user