refactor(test): make bom update tool tests deterministic

This commit is contained in:
ruthra kumar
2025-11-21 13:44:31 +05:30
parent 8c5276c5e1
commit 7b26a4c2eb
6 changed files with 266 additions and 3 deletions

View File

@@ -24,6 +24,11 @@ from erpnext.tests.utils import ERPNextTestSuite
class TestBOM(ERPNextTestSuite):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.load_test_records("BOM")
@timeout
def test_get_items(self):
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict

View File

@@ -0,0 +1,192 @@
[
{
"items": [
{
"amount": 5000.0,
"doctype": "BOM Item",
"item_code": "_Test Serialized Item With Series",
"parentfield": "items",
"qty": 1.0,
"rate": 5000.0,
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
"include_item_in_manufacturing": 1
},
{
"amount": 2000.0,
"doctype": "BOM Item",
"item_code": "_Test Item 2",
"parentfield": "items",
"qty": 2.0,
"rate": 1000.0,
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
"include_item_in_manufacturing": 1
}
],
"docstatus": 1,
"doctype": "BOM",
"currency": "USD",
"is_active": 1,
"is_default": 1,
"item": "_Test Item Home Desktop Manufactured",
"company": "_Test Company",
"quantity": 1.0
},
{
"scrap_items":[
{
"amount": 2000.0,
"doctype": "BOM Scrap Item",
"item_code": "_Test Item Home Desktop 100",
"parentfield": "scrap_items",
"stock_qty": 1.0,
"rate": 2000.0,
"stock_uom": "_Test UOM"
}
],
"items": [
{
"amount": 10000.0,
"doctype": "BOM Item",
"item_code": "_Test Item",
"parentfield": "items",
"qty": 1.0,
"rate": 5000.0,
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
"include_item_in_manufacturing": 1
},
{
"amount": 2000.0,
"doctype": "BOM Item",
"item_code": "_Test Item Home Desktop 100",
"parentfield": "items",
"qty": 2.0,
"rate": 1000.0,
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
"include_item_in_manufacturing": 1
}
],
"docstatus": 1,
"doctype": "BOM",
"is_active": 1,
"is_default": 1,
"currency": "USD",
"item": "_Test FG Item",
"quantity": 1.0
},
{
"operations": [
{
"operation": "_Test Operation 1",
"description": "_Test",
"workstation": "_Test Workstation 1",
"hour_rate": 100,
"time_in_mins": 60,
"operating_cost": 100
}
],
"items": [
{
"amount": 5000.0,
"doctype": "BOM Item",
"item_code": "_Test Item",
"parentfield": "items",
"qty": 1.0,
"rate": 5000.0,
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
"include_item_in_manufacturing": 1
},
{
"amount": 3000.0,
"bom_no": "BOM-_Test Item Home Desktop Manufactured-001",
"doctype": "BOM Item",
"item_code": "_Test Item Home Desktop Manufactured",
"parentfield": "items",
"qty": 3.0,
"rate": 1000.0,
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
"include_item_in_manufacturing": 1
}
],
"docstatus": 1,
"doctype": "BOM",
"is_active": 1,
"is_default": 1,
"currency": "USD",
"conversion_rate": 60,
"company": "_Test Company",
"item": "_Test FG Item 2",
"quantity": 1.0,
"with_operations": 1
},
{
"operations": [
{
"operation": "_Test Operation 1",
"description": "_Test",
"workstation": "_Test Workstation 1",
"time_in_mins": 60,
"operating_cost": 140
}
],
"items": [
{
"amount": 5000.0,
"doctype": "BOM Item",
"item_code": "_Test Item",
"parentfield": "items",
"qty": 2.0,
"rate": 3000.0,
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
"include_item_in_manufacturing": 1
}
],
"docstatus": 1,
"doctype": "BOM",
"is_active": 1,
"is_default": 1,
"currency": "USD",
"item": "_Test Variant Item",
"quantity": 1.0,
"with_operations": 1
},
{
"items": [
{
"amount": 5000.0,
"doctype": "BOM Item",
"item_code": "_Test Item",
"parentfield": "items",
"qty": 2.0,
"rate": 3000.0,
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
"include_item_in_manufacturing": 1
}
],
"docstatus": 1,
"doctype": "BOM",
"is_active": 1,
"is_default": 1,
"currency": "USD",
"item": "_Test Variant Item",
"quantity": 1.0,
"with_operations": 0,
"fg_based_operating_cost": 1,
"operating_cost_per_bom_quantity": 140
}
]

View File

@@ -17,6 +17,11 @@ from erpnext.tests.utils import ERPNextTestSuite
class TestBOMUpdateLog(ERPNextTestSuite):
"Test BOM Update Tool Operations via BOM Update Log."
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.load_test_records("BOM")
def setUp(self):
bom_doc = frappe.copy_doc(self.globalTestRecords["BOM"][0])
bom_doc.items[1].item_code = "_Test Item"

View File

@@ -16,6 +16,11 @@ from erpnext.tests.utils import ERPNextTestSuite
class TestBOMUpdateTool(ERPNextTestSuite):
"Test major functions run via BOM Update Tool."
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.load_test_records("BOM")
def tearDown(self):
frappe.db.rollback()

View File

@@ -30,6 +30,9 @@ class TestJobCard(ERPNextTestSuite):
@classmethod
def setUpClass(cls):
super().setUpClass()
# used in job card time log
cls.make_employees()
cls.load_test_records("BOM")
def setUp(self):
self.make_employees() # used in job card time log

View File

@@ -132,13 +132,13 @@ class ERPNextTestSuite(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.make_presets()
cls.make_persistent_master_data()
# initilize global test records attribute
if not hasattr(cls, "globalTestRecords"):
cls.globalTestRecords = {}
cls.make_presets()
cls.make_persistent_master_data()
@classmethod
def load_test_records(cls, doctype):
if doctype not in cls.globalTestRecords:
@@ -239,6 +239,9 @@ class ERPNextTestSuite(unittest.TestCase):
cls.make_loyalty_program()
cls.make_shareholder()
cls.make_sales_taxes_template()
cls.make_workstation()
cls.make_operation()
cls.make_bom()
cls.update_selling_settings()
cls.update_stock_settings()
cls.update_system_settings()
@@ -2786,6 +2789,56 @@ class ERPNextTestSuite(unittest.TestCase):
)
)
@classmethod
def make_operation(cls):
records = [
{"doctype": "Operation", "name": "_Test Operation 1", "workstation": "_Test Workstation 1"}
]
cls.operation = []
for x in records:
if not frappe.db.exists("Operation", {"name": x.get("name")}):
cls.operation.append(frappe.get_doc(x).insert())
else:
cls.operation.append(frappe.get_doc("Operation", {"name": x.get("name")}))
@classmethod
def make_workstation(cls):
records = [
{
"doctype": "Workstation",
"name": "_Test Workstation 1",
"workstation_name": "_Test Workstation 1",
"warehouse": "_Test warehouse - _TC",
"hour_rate_labour": 25,
"hour_rate_electricity": 25,
"hour_rate_consumable": 25,
"hour_rate_rent": 25,
"holiday_list": "_Test Holiday List",
"working_hours": [{"start_time": "10:00:00", "end_time": "20:00:00"}],
}
]
cls.workstation = []
for x in records:
if not frappe.db.exists("Workstation", {"workstation_name": x.get("workstation_name")}):
cls.workstation.append(frappe.get_doc(x).insert())
else:
cls.workstation.append(
frappe.get_doc("Workstation", {"workstation_name": x.get("workstation_name")})
)
@classmethod
def make_bom(cls):
# TODO: replace JSON source with hardcoded data in py
cls.load_test_records("BOM")
records = cls.globalTestRecords["BOM"]
cls.bom = []
for x in records:
x["company"] = cls.companies[0].name
if not frappe.db.exists("BOM", {"item": x.get("item"), "company": x.get("company")}):
cls.bom.append(frappe.get_doc(x).insert())
else:
cls.bom.append(frappe.get_doc("BOM", {"item": x.get("item"), "company": x.get("company")}))
@contextmanager
def set_user(self, user: str):
try: