What both @Bilal and @Samir have said is accurate and true. However, I strongly recommend you try to avoid inserting custom settings instances into the database as part of your unit testing; we used to do this and it basically prevented us from using parallel test execution.
There is an "edge case" (or perhaps infrastructure bug) in the way that Salesforce manages the transaction isolation of inserts of custom settings into the database - we would find that two potentially entirely independent tests that happened to run in parallel and where both inserted a custom setting instance (for the same custom settings type) into the database could randomly fail with a database locking error.
The solution we applied was to ensure that all access to custom settings instances was indirected via a class, along these lines (this is actually simplified compared with what we do, but gives an idea of the approach):
public class Settings {
/**
* The cached example settings instance.
*/
private static Example_Settings__c exampleSettings = null;
/**
* Returns the org default settings instance for example settings. This value
* is cached, so any updates to the instance during a given session/request
* against the Salesforce org will be retained through to the end of the session.
*/
public static Example_Settings__c getExample() {
if (exampleSettings == null) {
// There's no cache settings instance, so get one from the database
exampleSettings = Example_Settings__c.getInstance();
if (exampleSettings == null) {
// There's none in the database so construct a "default" instance
exampleSettings = (Example_Settings__c) Example_Settings__c.getSObjectType().newSObject(null, true);
}
}
return exampleSettings;
}
}
Because this code basically caches the settings in memory, this works nicely where the unit test wants to initialize the settings that the production code will then use, like:
@IsTest
void testWithSettings() {
Example_Settings__c exampleSettings = Settings.getExample();
// This updates the cached instance, so when the production code gets the settings
// using Settings.getExample() the production code will see these values
exampleSettings.Some_Setting_Value__c = 123;
exampleSettings.Some_Other_Setting_Value__c = 'abc';
// So now you can call the production code and it will see the values 123 and abc
...
}
Clearly this could be quite a task to implement, but you will avoid problems caused by this "edge case" behaviour whilst still being able to run tests in parallel.