Wieso krieg ich die Unit Tests nicht hin

KonradN

Super-Moderator
Mitarbeiter
Aber die Methode, die eben dies berechnet macht genau dieses und daher kann das auch nur getestet werden.

Die Berechnung vom Spielerleben oder so ist woanders und wird daher auch woanders getestet.

Aber klar: bei einer Methode, die etwas ausrechnet, da testet man nur, ob diese etwas richtig ausrechnet.
 
Y

yfons123

Gast
die problematik ohne Prozent rechnung ein Schadenssystem aufzubauen resultiert dann wie in Gothic3 wo man am ende einfach alles one shotted deswegen wollte ich ein skalierungs system das "umso mehr umso weniger bekommst du" macht

hier ist dann mal die skalierung dargestellt wie ich es mir ungefähr vorgestellt habe
Grün = Blunt in der XML => es hilft nichts ob ich 150 oder 1000 rüstung habe, "Prügel schaden" wie zb Streitkolben sollte immer viel schaden machen
Schwarz = Pierce in der XML => wenn ich wenig rüstung habe dagegen bekomm ich viel schaden, bei viel rüstung weniger
Blau = Blade in der XML => der durchschnitt daraus

jede waffe und Rüstung sollte alle "stats" haben die möglich sind wie zb eine EisenRüstung hätte
Java:
Blunt=100
Pierce=100
Blade=100
damit hätte "nach der formel" die rüstung diese REduktions werte
eine auswirkung von
Blunt=60%
Pierce=60%
Blade=85%

wobei man dann wieder sagen könnte ich könnte den ganzen kram auch linear machen und einfach die werte der rüstung so setzen dass es passt...

1674928008273.png
XML:
<?xml version="1.0" encoding="UTF-8"?>
<ResistanceCollection xmlns="ResistanceCollection">
    <ArmorEffect>
        <Name>Blunt</Name>
        <ReductionMultiplier>0.8</ReductionMultiplier>
        <Divider>20</Divider>
    </ArmorEffect>
    <ArmorEffect>
        <Name>Blade</Name>
        <ReductionMultiplier>1.5</ReductionMultiplier>
        <Divider>70</Divider>
    </ArmorEffect>
    <ArmorEffect>
        <Name>Pierce</Name>
        <ReductionMultiplier>2</ReductionMultiplier>
        <Divider>200</Divider>
    </ArmorEffect>
</ResistanceCollection>
 
Zuletzt bearbeitet von einem Moderator:
Y

yfons123

Gast
wobei es hier eigentlich sinnvoller zu sagen: ich habe X rüstung, wie schauts auf dem Graphen aus

zb 100 rüstung würde in 60 60 85 resultieren...

es ist halt scheiße wenn man nicht mal weis was es sein sollte
 

AndiE

Top Contributor
Momentan knabbere ich immer noch an dem Diagramm "prozenturaler Schaden ist Funktion von Rüstung mit dem Parameter Stabilität"

Da es hier ja nicht um Rollenspiele geht, würde ich mal auf das Thema "Testen" zurückkommen,

Die Codeschnippel sind ungetestet und auch nicht syntaxfehlerfrei. Es geht mir nur mal um das Prinzip.

Im Prinzip würde ich den Ablauf so denken:

Java:
HEALTH=100;
STRENGHT=80;
ARMOR=50;
STABILITY=50;
h1= new Hero(HEALTH,STRENGTH,ARMOR,STABILITY);
EFFECT=50;
w1= new Weapon(EFFECT);
int power= 50;
damage=h1.attac(w1, power);
h1.wounded(damage);

Für alle Nichtrollenspieler: Hier wird ein Held h1 angelegt, der die Attribute Gesundheit, Stärke, Rüstung hat,. Zuätzlich gibt es noch eine Option Stabilität, die für die Stabilität der Rüstung steht. Dann wird ein Objekt w1 angelegt, dass für eine Waffe steht. Diese hat die Eigenschaft Effektivitivät. Ein Messer ist weniger effektiv als ein Schwert.

Die wichigste Methode ist die "attac"-Methode, wo der Held mit der Waffe attakiert wird, wobei die Waffe mit der Kraft "power" geführt wird. Ein kraftvoll geführter Stich mach mehr Schaden als ein Ritzen.


Java:
public class Held{
...

    int attac(Weapon w, int power){
        int damage;
        // Code
        return damage;
    }

}

Das wäre in meinen Augen die zu testende Funktion.

Bis hierher würde ich übrigens tatsächlich nur die "äußere Hülle" der Klassen und Methoden schreiben, wenn ich mit TDD arbeiten würde.

Nun kann ich Tests schreiben, wo ich genau festlegen kann:

Wie stark wirkt die Rüstung? Wie stabil ist sie?
Wie groß ist der Schaden bei welcher Waffe, die mit welcher Intensität geführt wird?

Ein Test würde dann etwa so aussehen:

Code:
void damageTest(){

Hero h= new Hero(100,50,70,40)
Weapon messer= new Weapon(10)

assertEqual(h.damage(messer,100),20)
}

Und beim Test erhält man erst einen roten Balken. Und muss dann eben die Methode so umschreiben, dass man einen grünen Balken erhält.
Man kann dann auch die hier immer wieder auftauchende Formel einbinden.

Ich halte diesen Ablauf aber für die Arbeit für ziemlich sinnvoll. Weil ich denke, dass der Ablauf des Programmes für alle verständlicher wird.


Und man kann dann auch feststellen, wo Begrenzungen Sinn machen, und was sie eigentlich bedeuten.
 
Y

yfons123

Gast
gut nun habe ich nochmal hin und her geschaufelt vom aufbau her

ich habe jetzt ein Interface für die Rüstungs Konfiguration, damit sollte es egal werden woher man sie bekommt was bis jetzt noch nicht der Fall war
dann hab ich noch den Basis Resistenz wert eingefügt damit die Formeln mehr sinn ergeben
dann hab ich noch das mit "an xml gebunden" verworfen und durch das interface ersetzt
dann hab ich noch das sinnvoller aufbauen können dadurch dass es jetzt mehr an die Story gebunden ist, jetzt weis ich zumindest wo es damit hingehen soll

vllt tu ich die BaseResistance noch in das interface .. aber das ist ja nur ein Detail
C#:
using BfnDamage.Armory;
using Moq;

namespace BfnDamage;
public class ArmorEffectTests
{
    [TestCase(0.8f, 50f, 100f, 0.6333f)]
    [TestCase(-100900000f, 50f, 100f, 0.1f)]
    [TestCase(-100000000f, -1000000000f, 100f, 0.1f)]
    [TestCase(-100000000f, -1000000000f, 0f, 0.1f)]
    [TestCase(100000000f, 0.8f, 40f, 0.9f)]
    [TestCase(50f, 1000000f, 40f, 0.1f)]
    [TestCase(100000000f, 1000000f, 40f, 0.9f)]
    public void Calculate_ReturnsExpectedResult(float scalingFactor, float effectiveness, float armorValue, float expectedResult)
    {
        var mockArmorEffectMaterial = new Mock<IArmorMaterial>();
        mockArmorEffectMaterial.SetupGet(a => a.Scaling).Returns(scalingFactor);
        mockArmorEffectMaterial.SetupGet(a => a.Effectiveness).Returns(effectiveness);

        var armor = new Armor(armorValue);

        var result = armor.GetEffectivePercentage(mockArmorEffectMaterial.Object); ;

        Assert.That(result, Is.EqualTo(expectedResult).Within(0.01f));
    }
}
C#:
namespace BfnDamage.Armory;
public interface IArmorMaterial
{
    /// <summary>
    /// Name of the Armors Material
    /// </summary>
    public string Name { get; init; }
    /// <summary>
    /// Defines the maximum of an Armors Effectiveness in Relation to the Armor and <see cref="Effectiveness"/>
    /// </summary>
    public float Scaling { get; init; }
    /// <summary>
    /// Defines how Quick the Armor will reach its maximum Effectiveness
    /// The lower the quicker it will reach the Maximum.
    /// </summary>
    public float Effectiveness { get; init; }
}
C#:
namespace BfnDamage.Armory;
/// <summary>
/// Calculates the Effectiveness of an Armor
/// </summary>
public class Armor {
    public float LowestScalingFactor { get; init; } = 0f;
    public float LowestEffectiveness { get; init; } = 10f;
    public float BaseResistance { get; init; } = 0.1f;
    public float HighestResistance { get; init; } = 0.9f;
    private readonly float _armor;
    public Armor(float armor)
    {
        _armor= armor;
    }
    /// <summary>
    /// Transforms the Armor to the effective Reduction of damage.
    /// This value is Clamped by <see cref="BindToResistanceBorders(float)"/>
    /// </summary>
    /// <param name="armor">The amount of Armor that needs to be transformed to a Percentage</param>
    /// <returns>The Percentage of how much this Armor can reduce</returns>
    public virtual float GetEffectivePercentage(IArmorMaterial material)
    {
        var clampedEffect = BindToLowest(material.Effectiveness, LowestEffectiveness);
        var clampedFactor = BindToLowest(material.Scaling, LowestScalingFactor);
        return BindToResistanceBorders((_armor / (_armor+ clampedEffect) * clampedFactor) + BaseResistance);
    }
    /// <summary>
    /// clamps the value between <see cref="BaseResistance"/> and <see cref="HighestResistance"/> so it will always be an percentage between these two values.
    /// </summary>
    /// <param name="value"></param>
    /// <returns>Clamped value between <see cref="BaseResistance"/> and <see cref="HighestResistance"/></returns>
    private float BindToResistanceBorders(float value)
    {
        return Math.Clamp(value, BaseResistance, HighestResistance);
    }
    private float BindToLowest(float value, float lowestValue)
    {
        if (value < lowestValue)
            return lowestValue;
        return value;
    }
}
 

mrBrown

Super-Moderator
Mitarbeiter
ich hätte es nicht hingekriegt die grenzfälle zu betrachten, ich tu mich da eigentlich ziemlich schwer
bei einer Mathe formel wäre es da eigentlich das einfachste wenn man das jetzt mit deinen beispielen betrachtet.. und nicht mal da krieg ich es hin

wie denkt man dass man die grenzfälle raus bekommt? sollte ich mir den dämlichst möglichen fall überlegen?
Stichworte in die Richtung wären Äquivalenzklassen und Grenzwerte, zu beidem müsste man per Google auch was finden. Damit denkt man grad in solchen Fällen den Großteil der „kritischen“ Eingaben ab, vor allem aber auch die Invaliden Eingaben.

Was man in diesem Fall, wenn man das Innere der Methoden kennt, auch machen kann, ist sich Teil-Terme anzugucken. Man muss sich dann überlegen, welche Werte an den Stelle kritisch sein könnten, zB 0, 1, sehr hohe Werte, und dann ausgehend davon, welche Eingaben diese Werte provozieren. Damit fängt man dann in diesem Fall sowas wie Division durch 0 ab.

Als drittes kann man, wenn man die Funktion schon in geogebra oder so hat, sich einfach Beispielwerte als Tabelle geben lassen, und diese dann als Eingabe für die Tests zu nutzen. Dient dann gleichzeitig auch noch als schöne Doku.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Zrebna Wieso sollte man Null-Prüfungen nicht mit Optional-Objekten nutzen? Allgemeine Java-Themen 13
Zrebna Wieso sind eigentlich JUnit-Tests in src/test/java platziert - nur Konvention? Allgemeine Java-Themen 7
P Wieso benutzen PriorityQueues Heaps? Allgemeine Java-Themen 2
I Wieso funktioniert das nich? Allgemeine Java-Themen 5
F Input/Output NullPointerException, aber wieso? [Apache POI] Allgemeine Java-Themen 11
R MAC-Adresse eindeutig für einen PC ? Bezug zu Netzwerk, wieso ? Allgemeine Java-Themen 7
P Best Practice Wieso funktioniert der Modulo - Operator nicht? Allgemeine Java-Themen 2
J Jasper ireport - wieso beendet die Anwendung wenn ich die Preview schließe Allgemeine Java-Themen 1
I Interface Interface / Klasse - wieso Abstract? Allgemeine Java-Themen 13
A Methoden Generische Methode mit Arrays - Source Compatibility 1.7 benötigt, wieso? Allgemeine Java-Themen 3
S RemoteException wieso ? Allgemeine Java-Themen 6
J if else Anweisung macht nicht was es soll. Wieso? Allgemeine Java-Themen 10
P wieso kann ich auf bluej exportieren aber auf eclipse nicht? Allgemeine Java-Themen 2
DEvent Wieso ist Javadoc mit Html Tags? Allgemeine Java-Themen 47
D java.util.InputMismatchException im Scanner -wieso? Allgemeine Java-Themen 5
E Wieso returnt das hier 1? Allgemeine Java-Themen 3
DStrohma [Erledigt] Wieso kann ich Taste 'ENTER' in JTable nicht belegen? Allgemeine Java-Themen 2
C Wieso funktioniert das? Allgemeine Java-Themen 6
W Wieso funktioniert dieser Code hier? Allgemeine Java-Themen 6
S Wieso stehen in der API immer wieder abstrakte Methoden ? Allgemeine Java-Themen 7
lacyuu Schleife hängt sich auf, wieso?? Allgemeine Java-Themen 2
V Wieso meckert FindBugs da? Allgemeine Java-Themen 7
P Wieso HashMap-Zugriff mit Object, statt mit MyObject? Allgemeine Java-Themen 12
V Wieso Heap Space Problem? Allgemeine Java-Themen 14
J Wieso implementiert HTTPServlet Serializable? Allgemeine Java-Themen 2
P Wieso skalieren diese beiden Threads unterschiedlich gut? Allgemeine Java-Themen 16
zilti Wieso geht der StreamReader/Writer nicht? Allgemeine Java-Themen 5
T Wieso erfolgt keine Ausgabe. /Excel Allgemeine Java-Themen 19
G wieso wird der String des StringBuilder immer länger? Allgemeine Java-Themen 2
G wieso "implements" Allgemeine Java-Themen 13
S Problem mit generics -> ClassCastException und ka wieso Allgemeine Java-Themen 20
G Übergabe funzt nicht, aber wieso? Allgemeine Java-Themen 3
G NullPointer ? wieso? Allgemeine Java-Themen 7
I Wieso läuft Programm bei Kollegen aber nicht bei mir? Allgemeine Java-Themen 10
zilti LZW-gepackte Datei. Ich krieg ne Krise. Allgemeine Java-Themen 8
M Wo krieg' ich die Datei Servlet.jar Allgemeine Java-Themen 3
M Erzeugen einer Jar-Datei - Ich krieg's nit gebacken. Allgemeine Java-Themen 7
W Checkliste Unit Test Allgemeine Java-Themen 17
Y Wie sinnvolle unit tests schreiben Allgemeine Java-Themen 29
sascha-sphw Erste Schritte Unit und Integration-Tests im Java Modul System Allgemeine Java-Themen 10
B Frage zu Unit-Tests Allgemeine Java-Themen 6
J Alle Unit Tests in Maven Modul Projekt ausführen Allgemeine Java-Themen 7
looparda Unit Test - Abgänigkeit zur Datenbank isolieren Allgemeine Java-Themen 3
R Unit Test Allgemeine Java-Themen 1
M Für was schreibt man Unit-Tests? Allgemeine Java-Themen 55
P J-Unit vergleich von 2 Objekten merkwürdig Allgemeine Java-Themen 7
G ThreadLocal in Muster "Unit of Work" Allgemeine Java-Themen 7
K Unit Test consolen ein-/ausgaben. Allgemeine Java-Themen 7
M Html Unit Whitespace-Problem Allgemeine Java-Themen 4
fastjack Unit-Testen mit Mocks Allgemeine Java-Themen 6
Jay_030 Guice: Frage im Umgang mit Unit-Tests Allgemeine Java-Themen 4
B FileWriter / FileReader testen / Mock-Objekt für Unit Tests? Allgemeine Java-Themen 6
S Unit Testing mit JMock Allgemeine Java-Themen 11
alexpetri unit tests für pdfs Allgemeine Java-Themen 4
B J-Unit Tests. Alle Tests eines Package einsammen. Allgemeine Java-Themen 4
tfa Unit-Tests für private Methoden Allgemeine Java-Themen 25
W Unit Tests im "Hauptprojekt" oder in Modulen Allgemeine Java-Themen 3
M Eine Frage über Unit-Tests mit Java Allgemeine Java-Themen 2
N Ausgaben (System.out) umlenken und in Unit-Tests überprüfen? Allgemeine Java-Themen 2

Ähnliche Java Themen


Oben