diff --git a/Content.IntegrationTests/Tests/Nutrition/HungerThirstTest.cs b/Content.IntegrationTests/Tests/Nutrition/HungerThirstTest.cs
new file mode 100644
index 0000000000..7a5195800e
--- /dev/null
+++ b/Content.IntegrationTests/Tests/Nutrition/HungerThirstTest.cs
@@ -0,0 +1,97 @@
+using Content.IntegrationTests.Tests.Interaction;
+using Content.Shared.Chemistry.Components;
+using Content.Shared.Nutrition.Components;
+using Content.Shared.Nutrition.EntitySystems;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Prototypes;
+
+namespace Content.IntegrationTests.Tests.Nutrition;
+
+///
+/// Tests the mechanics of hunger and thirst.
+///
+public sealed class HungerThirstTest : InteractionTest
+{
+ private readonly EntProtoId _drink = "DrinkLemonadeGlass";
+ private readonly EntProtoId _food = "FoodCakeVanillaSlice";
+ protected override string PlayerPrototype => "MobHuman";
+
+ ///
+ /// Tests that hunger and thirst values decrease over time (low means hungrier and thirstier).
+ /// Tests that hunger and thirst values increase when eating/drinking (high means less hungry and thirsty).
+ ///
+ [Test]
+ public async Task HungerThirstIncreaseDecreaseTest()
+ {
+ // Ensure that the player can breathe and not suffocate
+ await AddAtmosphere();
+
+ var hungerComponent = Comp(Player);
+ var thirstComponent = Comp(Player);
+ var hungerSystem = SEntMan.System();
+ var thirstSystem = SEntMan.System();
+ var ingestionSystem = SEntMan.System();
+
+ // Set initial value
+ hungerSystem.SetHunger(SPlayer, hungerComponent.Thresholds[HungerThreshold.Okay], hungerComponent);
+ thirstSystem.SetThirst(SPlayer, thirstComponent, thirstComponent.ThirstThresholds[ThirstThreshold.Okay]);
+
+ // Ensure hunger and thirst value decrease over time (the Urist gets hungrier/thirstier)
+ var previousHungerValue = hungerSystem.GetHunger(hungerComponent);
+ var previousThirstValue = thirstComponent.CurrentThirst; // TODO: combined sation system with a sane API
+
+ // Simulate long enough for both update loops to run
+ var runTime = Math.Max((float)hungerComponent.ThresholdUpdateRate.TotalSeconds, (float)thirstComponent.UpdateRate.TotalSeconds) + 1f;
+ await RunSeconds(runTime);
+
+ var currentHungerValue = hungerSystem.GetHunger(hungerComponent);
+ Assert.That(currentHungerValue, Is.LessThan(previousHungerValue), "Hunger value did not decrease over time");
+ previousHungerValue = currentHungerValue;
+
+ var currentThirstValue = thirstComponent.CurrentThirst;
+ Assert.That(currentThirstValue, Is.LessThan(previousThirstValue), "Thirst value did not decrease over time");
+ previousThirstValue = currentThirstValue;
+
+ // Now we spawn food in the Urist's hand
+ await PlaceInHands(_food);
+
+ // We eat the food in hand
+ await UseInHand();
+
+ // To see a change in hunger, we need to wait at least 30 seconds
+ await RunSeconds(30);
+
+ // We ensure the food is fully eaten
+ var foodEaten = HandSys.GetActiveItem((SPlayer, Hands));
+ Assert.That(foodEaten, Is.Null, "Food item did not disappear after eating it");
+
+ // Ensure that the hunger value has increased (The Urist is less hungry)
+ Assert.That(hungerSystem.GetHunger(hungerComponent), Is.GreaterThan(previousHungerValue), "Hunger value did not increase after eating food");
+
+ // Now we spawn a drink in the Urist's hand
+ var drink = await PlaceInHands(_drink);
+
+ // Get the solution that can be consumed
+ Assert.That(ingestionSystem.CanConsume(SPlayer, SPlayer, ToServer(drink), out var solution, out _),
+ "Unable to get the solution or the entity can not be consumed");
+
+ // Find the initial amount of solution in the drink
+ var initialSolutionVolume = solution.Value.Comp.Solution.Volume;
+
+ // We drink the drink in hand
+ await UseInHand();
+
+ // To see a change in thirst, we need to wait at least 30 seconds
+ await RunSeconds(30);
+
+ // Ensure the solution volume has decreased
+ Assert.That(solution.Value.Comp.Solution.Volume, Is.LessThan(initialSolutionVolume), "Solution volume did not decrease after drinking");
+
+ // Ensure that the thirst value has increased (The Urist is less thirsty)
+ Assert.That(thirstComponent.CurrentThirst, Is.GreaterThan(previousThirstValue), "Thirst value did not increase after drinking");
+
+ // Make sure that the glass did not get deleted after drinking from it
+ var glass = HandSys.GetActiveItem((SPlayer, Hands));
+ Assert.That(glass, Is.Not.Null, "Glass got deleted after drinking from it");
+ }
+}