I subscribe to FIRST - Fast, Independent, Repeatable, Self-Validating, and Timely. Tests need to run as fast as possible (no implicit waits or sleeps), run by itself with the same expected results, can be ran back-to-back with itself (before and after deployments), end with an Assert (I also follow Arrange, Act, Assert), and run as part of CI with reliable and easily parse-able results.
You want to test everything as simply as possible but often one function relies on another. For our example, we need to log in and then update our profile. So we can't test the 'Profile' page without first hitting the 'Log In' page. Well, we already have a small, happy-path test for logins that might look like:
public void Login_HappyPath()
// Arrange: Get necessary values
User user = User.GetUser("admin");
// Act: Login using valid credentails
// Assert: Login was successful
With each test that needs to login first, we just call the login method and move on with life. If the login doesn't work for whatever reason, then we'll never be able to test the 'Profile' page as the test(s) would likely throw an exception trying to get there.
Things start getting a little more complicated with something like CRUD (Create, Read, Update, Delete) operations. With the Read, we need a record as a prerequisite. There are many ways you can get a record for testing. You could seed the data in the 'Arrange' part of your test or you could have specific read-only test records in a database. The options go on.
public void Read_HappyPath()
// Arrange: Get the ID for the test record
string recordId = TestUtils.GetTestRecord("read_happypath");
// Act: Request the record by ID
JObject recordJsonObject = App.RecordsPage.RequestById(recordId);
// Assert: The record
Takeaway: First, test everything as small as you can ('unit' tests). Then start chaining common methods into other ('integration') tests. Don't be surprised when an 'integration' test fails as you'll likely be able to track it back to a 'unit' test. Do take care in test design so that one test can run by itself. Note: I am using the terms 'unit' and 'integration' loosely here.