In short, Glide is not a traditional dev environment.
At my day job, we have Dev, Test, and Prod environments, and likewise there are Dev, Test, and Prod databases. I work with a DB2 database on a mainframe, as well as SQL Server on some of our windows servers. On top of that we have mainframe applications as well as web and PC applications that use that same database. In the applications, it’s easy to switch out which database you are pointing to, because it’s as simple as changing a library list, or changing a database connection. Also, as expected, we promoted applications through each environment until they get to production…and each environment points to it’s respective database.
I’m well aware of a traditional development environment, but Glide doesn’t exactly work that traditional way, and it’s important to grasp that. Glide does not have separate environments. But, like @ThinhDinh said, you can turn auto publishing off and control when user interface changes are published. Data on the other hand is a different story. Data in glide in much more ingrained into the app. It’s not like traditional development where you can determine your database connection separately when the app is ran. Instead, it’s like the data is the app, with a UI skin on top of it.
While you can control publishing of changes to the UI, the data itself is always live. Any changes to data, changes to the layout or formatting of data, or removing columns will most definitely affect a live app, even if you have publishing turned off. With glide, you can’t simply switch out a database at will. There is only one connection to data and it’s essentially permanent. It’s not as simple as changing out a database connection. I mean, you can, but it’s a lot of work and really depends on your data sources. You could change out tables, but you may also be rebuilding screens to connect to those different database tables. The whole glide interface is deeply connected to table ID’s and table header ID’s. That’s why you can change a table name or change a column header name, and it’s updated everywhere in your app, unlike a traditional dev environment where you would probably have to update a bunch of SQL to match new and updated columns or table names.
If you really wanted, you could duplicate an app, as well as all of the data, and then make your changes to that duplicate copy of the app, but then switching out apps when you are ready for production would involve switching out urls, custom domains, and manually updating data in your duplicated tables so it matches the current live data. It becomes a whole lot of work.
My recommendation would be to turn off auto publishing. Make your changes, and when you are ready for production, publish the changes. If you do anything with data, be VERY mindful of what you are changing. Like I said, data is always live. There is no dev or test version of data. If you need to, make duplicates of columns for the new interface changes to use, while leaving existing column undisturbed for the live version of the app.
Personally I just make my changes in live. If they are minor changes, I just go ahead and do it. If it’s something more substantial, I may add a new screen or tab with the visibility set so only I can see it. Then I can still play with the published app on my phone to test things out. But my user base is two people and I’m dating one of them, so it’s not so crucial if someone sees something while I’m in the middle of making changes. 
Overall, Glide is just different and sometimes you need to switch off your traditional programming brain to understand how glide works for non-programmers who may not understand that way of thinking. Maybe someday Glide will build a more robust development environment with different environment capability, but I don’t see it coming anytime soon though, because I imagine it would be a massive undertaking to take glide to that level of development control.