test: contextmanager to change settings
diff --git a/erpnext/tests/utils.py b/erpnext/tests/utils.py
index 16ecd51..11eb6af 100644
--- a/erpnext/tests/utils.py
+++ b/erpnext/tests/utils.py
@@ -1,7 +1,8 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+import copy
+from contextlib import contextmanager
import frappe
@@ -41,3 +42,38 @@
contact.add_email("test_contact_customer@example.com", is_primary=True)
contact.add_phone("+91 0000000000", is_primary_phone=True)
contact.insert()
+
+
+@contextmanager
+def change_settings(doctype, settings_dict):
+ """ A context manager to ensure that settings are changed before running
+ function and restored after running it regardless of exceptions occured.
+ This is useful in tests where you want to make changes in a function but
+ don't retain those changes.
+ import and use as decorator to cover full function or using `with` statement.
+
+ example:
+ @change_settings("Stock Settings", {"item_naming_by": "Naming Series"})
+ def test_case(self):
+ ...
+ """
+
+ try:
+ settings = frappe.get_doc(doctype)
+ # remember setting
+ previous_settings = copy.deepcopy(settings_dict)
+ for key in previous_settings:
+ previous_settings[key] = getattr(settings, key)
+
+ # change setting
+ for key, value in settings_dict.items():
+ setattr(settings, key, value)
+ settings.save()
+ yield # yield control to calling function
+
+ finally:
+ # restore settings
+ settings = frappe.get_doc(doctype)
+ for key, value in previous_settings.items():
+ setattr(settings, key, value)
+ settings.save()