Which approach is the best? Testing on real devices or simulators/emulators?This is a tough question because both options offer different levels of testability and flexibility when testing. There are also many problems associated with each. So my answer will be again: “It depends on your needs!”.
Running test on a device is, always in my opinion, the best solution because it offers a testing environment completely aligned with the running environment: tests run on those devices where your apps will be used once published on stores. However devices must be connected to the Appium server via USB at least, and this is not always a very nice thing. ADB has a known issue for which a device disconnects after a while (even though it remained plugged all the time): because of this your tests might fail after a while and Appium will report that a device could not be found! I had to write a component which resets ADB after some time so that devices will not disconnect.