From 7e22efde3f3be8d9f39856eb704d438feae8eb0f Mon Sep 17 00:00:00 2001 From: Serghei Cebotari Date: Fri, 29 Dec 2023 11:24:23 +0300 Subject: [PATCH] Implement Data driven tests --- RhSolutions.ML.Tests/DatasetBase.cs | 22 ++ RhSolutions.ML.Tests/RaupianoTests.cs | 16 - RhSolutions.ML.Tests/RautitanPipesTests.cs | 32 -- ...titanFittingsTests.cs => RautitanTests.cs} | 56 ++-- RhSolutions.ML.Tests/RhSolutionsDataset.cs | 6 + .../{RhSolutionsTests.cs => TestBase.cs} | 14 +- RhSolutions.ML.Tests/TestData/Rautitan.csv | 273 ++++++++++++++++++ 7 files changed, 343 insertions(+), 76 deletions(-) create mode 100644 RhSolutions.ML.Tests/DatasetBase.cs delete mode 100644 RhSolutions.ML.Tests/RaupianoTests.cs delete mode 100644 RhSolutions.ML.Tests/RautitanPipesTests.cs rename RhSolutions.ML.Tests/{RautitanFittingsTests.cs => RautitanTests.cs} (97%) create mode 100644 RhSolutions.ML.Tests/RhSolutionsDataset.cs rename RhSolutions.ML.Tests/{RhSolutionsTests.cs => TestBase.cs} (76%) create mode 100644 RhSolutions.ML.Tests/TestData/Rautitan.csv diff --git a/RhSolutions.ML.Tests/DatasetBase.cs b/RhSolutions.ML.Tests/DatasetBase.cs new file mode 100644 index 0000000..904bab3 --- /dev/null +++ b/RhSolutions.ML.Tests/DatasetBase.cs @@ -0,0 +1,22 @@ +using System.Collections; + +namespace RhSolutions.ML.Tests; +public abstract class DatasetBase : IEnumerable +{ + protected virtual string FileName {get;set;} = string.Empty; + public IEnumerator GetEnumerator() + { + string path = Path.Combine("..", "..", "..", "TestData", $"{FileName}.csv"); + using FileStream stream = new(path, FileMode.Open, FileAccess.Read); + StreamReader reader = new(stream); + string? inputLine = reader.ReadLine(); + while (inputLine != null) + { + var data = inputLine.Split(';'); + yield return new Product { Name = data[0], Type = data[1] }; + inputLine = reader.ReadLine(); + } + reader.Close(); + stream.Close(); + } +} diff --git a/RhSolutions.ML.Tests/RaupianoTests.cs b/RhSolutions.ML.Tests/RaupianoTests.cs deleted file mode 100644 index 57abcfa..0000000 --- a/RhSolutions.ML.Tests/RaupianoTests.cs +++ /dev/null @@ -1,16 +0,0 @@ -// namespace RhSolutions.ML.Tests; - -// public class RaupianoTests : RhSolutionsTests -// { -// [TestCase("Труба канализационная")] -// [TestCase("Труба 110")] -// [TestCase("Труба 110 500")] -// public void WastePipeTest(string name) -// => Execute(name, expectedGroup: "Труба RAUPIANO"); - -// [TestCase("Тройник 50/50/45")] -// [TestCase("Тройник 50/50/45°")] -// [TestCase("Тройник 50 50 45")] -// public void WastePipeBranchTest(string name) -// => Execute(name, expectedGroup: "Тройник RAUPIANO"); -// } diff --git a/RhSolutions.ML.Tests/RautitanPipesTests.cs b/RhSolutions.ML.Tests/RautitanPipesTests.cs deleted file mode 100644 index 77a0147..0000000 --- a/RhSolutions.ML.Tests/RautitanPipesTests.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace RhSolutions.ML.Tests; - -public class RautitanPipesTests : RhSolutionsTests -{ - [TestCase("Труба stabil 16")] - [TestCase("Труба stabil")] - public void StabilPipeTest(string name) - => Execute(name, expectedGroup: "Stabil"); - - [TestCase("Труба flex 16")] - [TestCase("Труба flex")] - public void FlexPipeTest(string name) - => Execute(name, expectedGroup: "Flex"); - - [TestCase("Труба pink 16")] - [TestCase("Труба pink")] - [TestCase("Унив. труба RAUTITAN pink+ 16х2,2 мм, бухта 120 м")] - [TestCase("Унив. труба RAUTITAN pink+ 63х8,7 мм, прямые отрезки 6 м")] - public void PinkPipeTest(string name) - => Execute(name, expectedGroup: "Pink"); - - [TestCase("Труба black 16")] - [TestCase("Труба black")] - [TestCase("Отоп. труба RAUTITAN black 20х2,8 мм, бухта 180 м")] - public void BlackPipeTest(string name) - => Execute(name, expectedGroup: "Black"); - - [TestCase("Фиксирующий желоб 16")] - [TestCase("Желоб 16")] - public void SupportingClipTest(string name) - => Execute(name, expectedGroup: "Желоб"); -} diff --git a/RhSolutions.ML.Tests/RautitanFittingsTests.cs b/RhSolutions.ML.Tests/RautitanTests.cs similarity index 97% rename from RhSolutions.ML.Tests/RautitanFittingsTests.cs rename to RhSolutions.ML.Tests/RautitanTests.cs index a33d2fe..1f51d8b 100644 --- a/RhSolutions.ML.Tests/RautitanFittingsTests.cs +++ b/RhSolutions.ML.Tests/RautitanTests.cs @@ -1,6 +1,10 @@ namespace RhSolutions.ML.Tests; -public class RautitanFittingsTests : RhSolutionsTests +public class RautitanTests : TestBase { + [TestCaseSource(typeof(RautitanDataset))] + public void RhSolutionsTests(Product expected) + => Execute(expected); + [TestCase("Гильза 16")] [TestCase("Пресс-втулка")] [TestCase("UPONOR Q&E EVOLUTION КОЛЬЦО БЕЛОЕ 16 '900Ф")] @@ -14,7 +18,7 @@ public class RautitanFittingsTests : RhSolutionsTests [TestCase("Тройник 50-50-32")] [TestCase("Тройник, 40 - 20 - 40")] [TestCase("Тройник, 50 - 32 - 50")] - public void TPieceTest(string name) + public void TPieceTest(string name) => Execute(name, expectedGroup: "Тройник RAUTITAN"); [TestCase("Муфта соединительная равнопроходная 16 PX")] @@ -38,7 +42,7 @@ public class RautitanFittingsTests : RhSolutionsTests [TestCase("переходник наружная резьба 16 1/2")] public void AdapterExternalTest(string name) => Execute(name, expectedGroup: "Переходник на наружную резьбу"); - + [TestCase("Переходник с внутренней резьбой 20-Rp 3/4 RX+")] [TestCase("Переходник с внутр. резьбой 20 1/2")] [TestCase("Переходник 16 1/2 ВР")] @@ -48,7 +52,7 @@ public class RautitanFittingsTests : RhSolutionsTests [TestCase("Переходник с внутренней резьбой 16xG 3/4\" для труб из сшитого полиэтилена аксиальный")] public void AdapterInternalTest(string name) => Execute(name, expectedGroup: "Переходник на внутреннюю резьбу"); - + [TestCase("Переходник с накидной гайкой 16-G 1/2 RX+")] [TestCase("Переходник с накидн. гайкой 16 1/2")] [TestCase("Переходник 16 1/2 НГ")] @@ -58,110 +62,110 @@ public class RautitanFittingsTests : RhSolutionsTests [TestCase("штуцер с накидной гайкой")] public void AdapterScrewcapTest(string name) => Execute(name, expectedGroup: "Переходник с накидной гайкой"); - + [TestCase("Угольник 16")] [TestCase("Угольник 16 90")] [TestCase("Угольник 50 45")] [TestCase("угольник 20/90")] public void ElbowTest(string name) => Execute(name, expectedGroup: "Угольник RAUTITAN"); - + [TestCase("Угольник-переходник с наружной резьбой 16-R 1/2 RX+")] [TestCase("Уголок соединительный с ниппелем 20 х 1/2'', бронза")] public void ThreadElbowExternalTest(string name) => Execute(name, expectedGroup: "Угольник с наружной резьбой"); - + [TestCase("Угольник-переходник с внутренней резьбой 16-Rp 1/2 RX+")] [TestCase("Уголок соединительный с муфтой 16 х 1/2\", бронза")] public void ThreadElbowInternalTest(string name) => Execute(name, expectedGroup: "Угольник с внутренней резьбой"); - + [TestCase("Угольник настенный с длинным патрубком, внутр. резьба 16-Rp 1/2 RX+")] [TestCase("Угольник настенный с внутр. резьбой 16-Rp 1/2 RX+")] [TestCase("Настенный угольник с внутренней резьбой (водорозетка), 16 - G 1/2\"")] public void ThreadElbowWallInternalTest(string name) => Execute(name, expectedGroup: "Угольник настенный внутренний"); - - + + [TestCase("Проточный настенный угольник 16/16-Rp 1/2 длинный RX+")] [TestCase("Проточный настенный угольник 16/20-Rp 1/2 короткий RX+")] [TestCase("Проточный угольник 16")] public void ThreadElbowDoubleWallInternalTest(string name) => Execute(name, expectedGroup: "Проточный настенный угольник"); - + [TestCase("Угольник настенный с наружной резьбой 16-R 1/2 RX+")] public void ThreadElbowWallExternalTest(string name) => Execute(name, expectedGroup: "Угольник настенный наружный"); - + [TestCase("Угольник-переходник с накидной гайкой 16-G 1/2 RX+")] [TestCase("Соединение угловое с накидной гайкой 16 х 1/2\", латунь")] public void ScrewcapElbowTest(string name) => Execute(name, expectedGroup: "Угольник с накидной гайкой"); - + [TestCase("Тройник RAUTITAN RX+ с наружной резьбой 16-16-R 1/2")] [TestCase("Тройник RAUTITAN RX+ с наружной резьбой 20-20-R 1/2")] public void ThreadTPieceExternal(string name) - => Execute(name, expectedGroup: "Тройник RAUTITAN резьбовой наружный"); - + => Execute(name, expectedGroup: "Тройник RAUTITAN резьбовой наружный"); + [TestCase("Тройник настенный с внутренней резьбой 16-Rp1/2-16 RX+")] [TestCase("Тройник с внутр. резьбой на боков. проходе 25-Rp 1/2-25 RX+")] [TestCase("Тройник-переходник с внутренней резьбой 25xR 3/4\" для труб из сшитого полиэтилена аксиальный")] public void ThreadTPieceInternal(string name) => Execute(name, expectedGroup: "Тройник RAUTITAN резьбовой внутренний"); - + [TestCase("Фиксатор поворота трубы 20/90°, без колец (оцинк. сталь)")] [TestCase("Фиксатор поворота трубы 32/90°, с кольцами (оцинк. сталь)")] [TestCase("Дуга 90° 25")] public void BendFormerHeating(string name) => Execute(name, expectedGroup: "Фиксатор поворота отопление"); - + [TestCase("Фиксатор поворота с кольцами 90°, 32")] [TestCase("Фиксатор поворота с кольцами 45°, 16")] public void BendFormerDrinking(string name) => Execute(name, expectedGroup: "Фиксатор поворота водоснабжение"); - + [TestCase("Трубка из. нерж. стали для подкл. радиатора, Г-образная 16/250")] [TestCase("Трубка L-образная - D15 16х15 для подключения радиатора, 250 мм")] [TestCase("Трубка L-образная")] [TestCase("Монтажная трубка для радиатора, конечная, 16 х 15 х 1100 мм")] public void ConnectionBendTest(string name) => Execute(name, expectedGroup: "Трубка Г-образная"); - + [TestCase("Трубка из. нерж. стали для подкл. радиатора, Т-образная 16/250")] [TestCase("Монтажная трубка для радиатора, проходная 16 х 15 х 300 мм")] [TestCase("Трубка T-образная - D15 16х15х16 для подключения радиатора")] public void ConnectionTeeTest(string name) => Execute(name, expectedGroup: "Трубка Т-образная"); - + [TestCase("Заглушка, 16, латунь")] [TestCase("Заглушка 16")] [TestCase("Заглушка для полимерн. трубы 16 RX+")] public void DummyPlugTest(string name) => Execute(name, expectedGroup: "Заглушка труб RAUTITAN"); - + [TestCase("Концовка разб. 3/4'' (еврок) для универс. трубы 16")] [TestCase("Переходник компрессионный PEX 20х2.8-G 3/4\" Евроконус")] [TestCase("Резьбозажимное соединение flex/pink 20х2,8xG3/4")] public void EuroconeFlexTest(string name) => Execute(name, expectedGroup: "Резьбозажимное flex"); - + [TestCase("Резьбозажимное соединение stabil 16,2x2,6xG3/4")] - [TestCase("Концовка разб.3/4''(еврок.) для PE-Xc и PE-MDXс 16")] + [TestCase("Концовка разб.3/4''(еврок.) для PE-Xc и PE-MDXс 16")] public void EuroconeStabilTest(string name) => Execute(name, expectedGroup: "Резьбозажимное stabil"); - + [TestCase("Переходник на евроконус 16-G 3/4")] [TestCase("Соед.прям. с вн.резьбой (н.гайка, еврок.) 16 ник.")] [TestCase("Переходник с накидной гайкой 16x2.2 -G 3/4\" Евроконус, c гильзой в комплекте")] public void EuroconeAdapterTest(string name) => Execute(name, expectedGroup: "Переходник на евроконус"); - + [TestCase("Резьбозажимное соединение для металлической трубки G 3/4 -15")] [TestCase("Концовка для монтажной трубы 15 х 1/2''")] [TestCase("Фитинг подключения L и T-образной медной трубки - D15 - G 3/4")] public void EuroconeConnectionBendTest(string name) => Execute(name, expectedGroup: "Резьбозажимное для трубки"); - + [TestCase("К-т двух резьбозажим. нипелей с нар.резьбой 1/2х3/4")] public void NippelTest(string name) => Execute(name, expectedGroup: "Ниппель"); diff --git a/RhSolutions.ML.Tests/RhSolutionsDataset.cs b/RhSolutions.ML.Tests/RhSolutionsDataset.cs new file mode 100644 index 0000000..0abe55f --- /dev/null +++ b/RhSolutions.ML.Tests/RhSolutionsDataset.cs @@ -0,0 +1,6 @@ +namespace RhSolutions.ML.Tests; + +public class RautitanDataset : DatasetBase +{ + protected override string FileName => "Rautitan"; +} diff --git a/RhSolutions.ML.Tests/RhSolutionsTests.cs b/RhSolutions.ML.Tests/TestBase.cs similarity index 76% rename from RhSolutions.ML.Tests/RhSolutionsTests.cs rename to RhSolutions.ML.Tests/TestBase.cs index 4e91342..679d9d3 100644 --- a/RhSolutions.ML.Tests/RhSolutionsTests.cs +++ b/RhSolutions.ML.Tests/TestBase.cs @@ -2,14 +2,14 @@ using RhSolutions.ML.Lib; namespace RhSolutions.ML.Tests; -public abstract class RhSolutionsTests +public abstract class TestBase { protected static string _appPath = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]) ?? "."; protected static string _dataPath = Path.Combine(_appPath, "..", "..", "..", "..", "Models", "model.zip"); protected MLContext _mlContext; protected PredictionEngine _predEngine; - public RhSolutionsTests() + public TestBase() { RhSolutionsMLBuilder.RebuildModel(); _mlContext = new MLContext(seed: 0); @@ -26,4 +26,14 @@ public abstract class RhSolutionsTests var prediction = _predEngine.Predict(p); Assert.That(prediction.Type, Is.EqualTo(expectedGroup)); } + + public void Execute(Product expected) + { + Product actual = new() + { + Name = expected.Name + }; + var prediction = _predEngine.Predict(actual); + Assert.That(prediction.Type, Is.EqualTo(expected.Type)); + } } \ No newline at end of file diff --git a/RhSolutions.ML.Tests/TestData/Rautitan.csv b/RhSolutions.ML.Tests/TestData/Rautitan.csv new file mode 100644 index 0000000..7e78a6a --- /dev/null +++ b/RhSolutions.ML.Tests/TestData/Rautitan.csv @@ -0,0 +1,273 @@ +Универсальн.труба RAUTITAN stabil PLATINUM 16,2х2,6 мм, бухта 100 м;Stabil +Универсальн.труба RAUTITAN stabil PLATINUM 20х2,9 мм, бухта 100 м;Stabil +Универсальн.труба RAUTITAN stabil PLATINUM 25х3,7 мм, бухта 50 м;Stabil +Универсальн.труба RAUTITAN stabil PLATINUM 32х4,7 мм, прям. отрезки 5м;Stabil +Универсальн.труба RAUTITAN stabil 16,2х2,6 мм, бухта 100 м;Stabil +Универсальн.труба RAUTITAN stabil 16,2х2,6 мм, бухта 300 м;Stabil +Универсальн.труба RAUTITAN stabil 20х2,9 мм, бухта 100 м;Stabil +Универсальн.труба RAUTITAN stabil 25х3,7 мм, бухта 50 м;Stabil +Универсальн.труба RAUTITAN stabil 32х4,7 мм, бухта 25 м;Stabil +Универсальн.труба RAUTITAN stabil 16,2х2,6 мм, прям.отрезки 5м;Stabil +Универсальн.труба RAUTITAN stabil 20х2,9 мм, прям.отрезки 5м;Stabil +Универсальн.труба RAUTITAN stabil 25х3,7 мм, прям.отрезки 5м;Stabil +Универсальн.труба RAUTITAN stabil 32х4,7 мм, прям.отрезки 5м;Stabil +Универсальн.труба RAUTITAN stabil 40х6,0 мм, прям.отрезки 5м;Stabil +Унив.труба RAUTITAN stabil 16,2х2,6, прямоуг. изол. 9 мм, бухта 25 м;Stabil +Унив.труба RAUTITAN stabil 20х2,9, прямоуг. изол. 9 мм, бухта 25 м;Stabil +Унив.труба RAUTITAN stabil 16,2х2,6, прямоуг., изол.26 мм, бухта 25 м;Stabil +Унив.труба RAUTITAN stabil 20х2,9, прямоуг., изол. 26 мм, бухта 25 м;Stabil +Унив.труба RAUTITAN stabil 16,2х2,6, кругл., изол. 4 мм, бухта 50 м;Stabil +Унив.труба RAUTITAN stabil 20х2,9, кругл., изол. 4 мм, бухта 50 м;Stabil +Унив.труба RAUTITAN stabil 25x3,7, кругл., изол. 4 мм, бухта 25 м. ;Stabil +Унив.труба RAUTITAN stabil 16,2х2,6, кругл., изол. 9 мм, бухта 50 м;Stabil +Унив.труба RAUTITAN stabil 20х2,9, кругл., изол. 9 мм, бухта 50 м;Stabil +Унив.труба RAUTITAN stabil 25x3,7, кругл., изол. 9 мм, бухта 25 м. ;Stabil +Унив.труба RAUTITAN stabil 16x2,6, кругл., изол. 13 мм, бухта 25 м.;Stabil +Унив.труба RAUTITAN stabil 20x2,9, кругл., изол. 13 мм, бухта 25 м. ;Stabil +Унив.труба RAUTITAN stabil 25x3,7, кругл., изол. 13 мм, бухта 25 м. ;Stabil +Унив.труба RAUTITAN stаbil 16,2х2,6мм в гофротрубе, бухта 50м;Stabil +Унив.труба RAUTITAN stabil 20х2,9мм в гофротрубе, бухта 50 м;Stabil +Унив.труба РЕХАУ FLEX 16x2,2, бухта 100м;Flex +Унив.труба РЕХАУ FLEX 20x2,8, бухта 100м;Flex +Унив.труба РЕХАУ FLEX 25x3,5, бухта 50м;Flex +Унив.труба РЕХАУ FLEX 32x4,4, бухта 50м;Flex +Унив.труба РЕХАУ FLEX 40x5,5, прям.отрезки 6м;Flex +Унив.труба РЕХАУ FLEX 50x6,9, прям.отрезки 6м;Flex +Унив.труба РЕХАУ FLEX 63x8,6, прям.отрезки 6м;Flex +Отоп. труба РЕХАУ PINK 16х2,2 мм, бухта 120 м;Pink +Отоп. труба РЕХАУ PINK 20х2,8 мм, бухта 120 м;Pink +Отоп. труба РЕХАУ PINK 25х3,5 мм, бухта 50 м;Pink +Отоп. труба РЕХАУ PINK 32х4,4 мм, бухта 50 м;Pink +Отоп.труба РЕХАУ BLACK 16х2,2 мм, бухта 200 м;Black +Отоп.труба РЕХАУ BLACK 20х2,8 мм, бухта 180 м;Black +Отоп.труба РЕХАУ BLACK 25х3,5 мм, бухта 100 м;Black +Фиксирующий желоб для ПЭ-трубы 16/17;Желоб +Фиксирующий желоб для ПЭ-трубы 20;Желоб +Фиксирующий желоб для ПЭ-трубы 25;Желоб +Фиксирующий желоб для ПЭ-трубы 32;Желоб +Фиксирующий желоб для ПЭ-трубы 40;Желоб +Фиксирующий желоб для ПЭ-трубы 50;Желоб +Фиксирующий желоб для ПЭ-трубы 63;Желоб +Монтажная гильза 16 PX;Монтажная гильза +Монтажная гильза 20 PX;Монтажная гильза +Монтажная гильза 25 PX;Монтажная гильза +Монтажная гильза 32 PX;Монтажная гильза +Монтажная гильза 40 PX;Монтажная гильза +Монтажная гильза 50 MX;Монтажная гильза +Монтажная гильза 63 MX;Монтажная гильза +Тройник равнопроходный 16-16-16 PX;Тройник RAUTITAN +Тройник равнопроходный 20-20-20 PX;Тройник RAUTITAN +Тройник равнопроходный 25-25-25 PX;Тройник RAUTITAN +Тройник равнопроходный 32-32-32 PX;Тройник RAUTITAN +Тройник равнопроходный 40-40-40 PX;Тройник RAUTITAN +Тройник равнопроходный 50-50-50 RX+;Тройник RAUTITAN +Тройник равнопроходный 63-63-63 RX+;Тройник RAUTITAN +Тройник равнопроходный 16-16-16 PLATINUM RX;Тройник RAUTITAN +Тройник равнопроходный 20-20-20 PLATINUM RX;Тройник RAUTITAN +Тройник равнопроходный 25-25-25 PLATINUM RX+;Тройник RAUTITAN +Тройник равнопроходный 32-32-32 PLATINUM RX+;Тройник RAUTITAN +Проточный настенный угольник 16/16-Rp 1/2 длинный RX+;Проточный настенный угольник +Проточный настенный угольник 20/20-Rp 1/2 длинный RX+;Проточный настенный угольник +Проточный настенный угольник 25/25-Rp 1/2 длинный RX+;Проточный настенный угольник +Проточный настенный угольник 16/16-Rp 1/2 короткий RX+;Проточный настенный угольник +Проточный настенный угольник 20/20-Rp 1/2 короткий RX+;Проточный настенный угольник +Проточный настенный угольник 16/20-Rp 1/2 короткий RX+;Проточный настенный угольник +Проточный настенный угольник 20/16-Rp 1/2 короткий RX+;Проточный настенный угольник +Проточный настенный угольник 25/25-Rp 1/2 короткий RX+;Проточный настенный угольник +Тройник RAUTITAN RX+ с наружной резьбой 16-16-R 1/2;Тройник RAUTITAN резьбовой наружный +Тройник RAUTITAN RX+ с наружной резьбой 20-20-R 1/2;Тройник RAUTITAN резьбовой наружный +Тройник RAUTITAN RX+ с наружной резьбой 20-20-R 3/4;Тройник RAUTITAN резьбовой наружный +Тройник с уменьшенным боковым проходом 20-16-20 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 25-16-25 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 25-20-25 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 32-16-32 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 32-20-32 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 32-25-32 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 40-20-40 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 40-25-40 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 40-32-40 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 50-20-50 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 50-25-50 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 50-32-50 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 50-40-50 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 63-25-63 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 63-32-63 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 63-40-63 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 63-50-63 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 20-16-20 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 25-16-25 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 25-20-25 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 32-20-32 PLATINUM RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым проходом 32-25-32 PLATINUM RX+;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 20-20-16 PX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 25-25-16 PX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 25-25-20 PX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 32-32-20 PX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 32-32-25 PX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 20-20-16 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным торцевым проходом 25-25-16 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 20-16-16 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-16-16 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-16-20 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-20-16 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-20-20 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 32-20-20 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 32-20-25 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 32-25-20 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 32-25-25 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 40-32-32 PX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 50-32-40 RX+;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 20-16-16 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-16-16 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-16-20 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 25-20-20 PLATINUM RX;Тройник RAUTITAN +Тройник с уменьшенным боковым и торцевым проходами 32-25-25 PLATINUM RX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 16-20-16 PX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 16-25-16 PX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 20-25-16 PX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 20-25-20 PX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 25-32-25 PX;Тройник RAUTITAN +Тройник с увеличенным боковым проходом 16-20-16 PLATINUM RX;Тройник RAUTITAN +Тройник настенный с внутренней резьбой 16-Rp1/2-16 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник настенный с внутренней резьбой 20-Rp1/2-16 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник настенный с внутренней резьбой 20-Rp1/2-20 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 25-Rp 1/2-25 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 25-Rp 3/4-25 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 32-Rp 3/4-25 RX+ ;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 32-Rp 3/4-32 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 32-Rp 1-32 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 40-Rp 1-40 RX+;Тройник RAUTITAN резьбовой внутренний +Тройник с внутр. резьбой на боков. проходе 50-Rp 1-50 RX+;Тройник RAUTITAN резьбовой внутренний +Муфта соединительная равнопроходная 16 PX;Муфта соединительная +Муфта соединительная равнопроходная 20 PX;Муфта соединительная +Муфта соединительная равнопроходная 25 PX;Муфта соединительная +Муфта соединительная равнопроходная 32 PX;Муфта соединительная +Муфта соединительная равнопроходная 40 PX;Муфта соединительная +Муфта соединительная равнопроходная 50 RХ+;Муфта соединительная +Муфта соединительная равнопроходная 63 RХ +;Муфта соединительная +Муфта соединительная равнопроходная 16 PLATINUM RX;Муфта соединительная +Муфта соединительная равнопроходная 25 PLATINUM RX;Муфта соединительная +Муфта соединительная равнопроходная 32 PLATINUM RX+;Муфта соединительная +Муфта соединительная переходная 20-16 PX;Муфта соединительная +Муфта соединительная переходная 25-16 PX;Муфта соединительная +Муфта соединительная переходная 25-20 PX;Муфта соединительная +Муфта соединительная переходная 32-25 PX;Муфта соединительная +Муфта соединительная переходная 40-32 PX;Муфта соединительная +Муфта соединительная переходная 40-25 RX+;Муфта соединительная +Муфта соединительная переходная 50-32 RX+;Муфта соединительная +Муфта соединительная переходная 50-40 RX+;Муфта соединительная +Муфта соединительная переходная 63-50 RX+;Муфта соединительная +Муфта соединительная переходная 20-16 PLATINUM RX;Муфта соединительная +Муфта соединительная переходная 25-16 PLATINUM RX;Муфта соединительная +Муфта соединительная переходная 25-20 PLATINUM RX;Муфта соединительная +Муфта соединительная переходная 32-25 PLATINUM RX;Муфта соединительная +Переходник с наружной резьбой 16-R 1/2 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 16-R 3/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 16-R 1 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 20-R 1/2 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 20-R 3/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 20-R 1 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 25-R 1/2 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 25-R 3/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 25-R 1 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 32-R 3/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 32-R 1 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 32-R 1 1/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 40-R 1 1/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 50-R 1 1/4 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 50-R 1 1/2 RX+;Переходник на наружную резьбу +Переходник с наружной резьбой 63-R 2 RX+;Переходник на наружную резьбу +Переходник с внутренней резьбой 16-Rp 1/2 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 20-Rp 1/2 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 20-Rp 3/4 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 25-Rp 1/2 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 25-Rp 3/4 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 25-Rp 1 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 32-Rp 3/4 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 32-Rр 1 RX+;Переходник на внутреннюю резьбу +Переходник с внутренней резьбой 40-Rр 1 1/4 RX+;Переходник на внутреннюю резьбу +Переходник с накидной гайкой 16-G 1/2 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 16-G 3/4 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 20-G 1/2 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 20-G 3/4 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 25-G 3/4 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 25-G 1 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 32-G 1 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 32-G 1 1/4 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 32-G 1 1/2 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 40-G 1 1/2 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 50-G 1 3/4 RX+;Переходник с накидной гайкой +Переходник с накидной гайкой 63-G 2 3/8 RX+;Переходник с накидной гайкой +Переходник на евроконус 20-G 3/4 ;Переходник на евроконус +Угольник-переходник с накидной гайкой 16-G 1/2 RX+;Угольник с накидной гайкой +Угольник-переходник с накидной гайкой 20-G 1/2 RX+;Угольник с накидной гайкой +Угольник 90°, 50 RX+;Угольник RAUTITAN +Угольник 90°, 63 RX+;Угольник RAUTITAN +Угольник 90°, 16 PX;Угольник RAUTITAN +Угольник 90°, 20 PX;Угольник RAUTITAN +Угольник 90°, 25 PX;Угольник RAUTITAN +Угольник 90°, 32 PX;Угольник RAUTITAN +Угольник 90°, 40 PX;Угольник RAUTITAN +Угольник 90° 16 PLATINUM RX;Угольник RAUTITAN +Угольник 90° 20 PLATINUM RX;Угольник RAUTITAN +Угольник 90° 32 PLATINUM RX+;Угольник RAUTITAN +Угольник 45°, 50 RX+;Угольник RAUTITAN +Угольник 45°, 63 RX+;Угольник RAUTITAN +Угольник 45°, 20 PX;Угольник RAUTITAN +Угольник 45°, 25 PX;Угольник RAUTITAN +Угольник 45°, 32 PX;Угольник RAUTITAN +Угольник 45°, 40 PX;Угольник RAUTITAN +Фиксатор поворота с кольцами 90°, 16;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 90°, 20;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 90°, 25;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 90°, 32;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 45°, 16;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 45°, 20;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 45°, 25;Фиксатор поворота водоснабжение +Фиксатор поворота с кольцами 45°, 32;Фиксатор поворота водоснабжение +Угольник-переходник с наружной резьбой 16-R 1/2 RX+;Угольник с наружной резьбой +Угольник-переходник с наружной резьбой 20-R 1/2 RX+;Угольник с наружной резьбой +Угольник-переходник с наружной резьбой 20-R 3/4 RX+;Угольник с наружной резьбой +Угольник-переходник с наружной резьбой 25-R 3/4 RX+;Угольник с наружной резьбой +Угольник-переходник с наружной резьбой 32-R 3/4 RX+;Угольник с наружной резьбой +Угольник-переходник с наружной резьбой 32-R 1 RX+;Угольник с наружной резьбой +Угольник-переходник с внутренней резьбой 16-Rp 1/2 RX+;Угольник с внутренней резьбой +Угольник-переходник с внутренней резьбой 16-Rp 3/4 RX+;Угольник с внутренней резьбой +Угольник-переходник с внутренней резьбой 20-Rp 1/2 RX+;Угольник с внутренней резьбой +Угольник-переходник с внутренней резьбой 20-Rp 3/4 RX+;Угольник с внутренней резьбой +Угольник-переходник с внутренней резьбой 25-Rp 1 RX+;Угольник с внутренней резьбой +Угольник настенный с внутр. резьбой 16-Rp 1/2 RX+;Угольник настенный внутренний +Угольник настенный с внутр. резьбой 20-Rp 1/2 RX+;Угольник настенный внутренний +Угольник настенный с внутр. резьбой 20-Rp 3/4 RX+;Угольник настенный внутренний +Угольник настенный с внутр. резьбой 25-Rp 3/4 RX+;Угольник настенный внутренний +Угольник настенный с длинным патрубком, внутр. резьба 16-Rp 1/2 RX+;Угольник настенный внутренний +Угольник настенный с длинным патрубком, внутр. резьба 20-Rp 1/2 RX+;Угольник настенный внутренний +Угольник настенный с наружной резьбой 16-R 1/2 RX+;Угольник настенный наружный +Угольник настенный с наружной резьбой 20-R 1/2 RX+;Угольник настенный наружный +Угольник настенный с наружной резьбой 20-R 3/4 RX+;Угольник настенный наружный +Угольник настенный с внутр. резьбой 16-Rp 1/2 длинный, 59 мм RX+;Угольник настенный внутренний +Угольник настенный с внутр. резьбой 20-Rp 1/2 длинный, 59 мм RX+;Угольник настенный внутренний +Угольник настенный с внутр. резьбой 16-Rp 1/2 длинный, 70 мм RX+;Угольник настенный внутренний +Угольник настенный с внутренней резьбой 20-Rp1/2 70мм RX+;Угольник настенный внутренний +Заглушка для полимерн. трубы 16 RX+;Заглушка труб RAUTITAN +Заглушка для полимерн. трубы 20 RX+;Заглушка труб RAUTITAN +Трубка РЕХАУ из. нерж. стали для подкл. радиатора, Г-образная 16/250 ;Трубка Г-образная +Трубка РЕХАУ из. нерж. стали для подкл. радиатора, Г-образная 16/500 ;Трубка Г-образная +Трубка РЕХАУ из. нерж. стали для подкл. радиатора, Г-образная 16/1000 ;Трубка Г-образная +Трубка РЕХАУ из. нерж. стали для подкл. радиатора, Г-образная 20/250 ;Трубка Г-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 16/250 ;Трубка Т-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 16/500 ;Трубка Т-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 16/1000 ;Трубка Т-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 20/250 ;Трубка Т-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 20/500 ;Трубка Т-образная +Трубка из. нерж. стали для подкл. радиатора, Т-образная 20/1000 ;Трубка Т-образная +К-т двух резьбозажим. нипелей с нар.резьбой 1/2х3/4 (латунь);Ниппель +Резьбозажимное соединение для металлической трубки G 3/4 -15;Резьбозажимное для трубки +Резьбозажимное соединение flex/pink 16х2,2xG3/4 ;Резьбозажимное flex +Резьбозажимное соединение flex/pink 20х2,8xG3/4 ;Резьбозажимное flex +Резьбозажимное соединение stabil 16,2x2,6xG3/4 ;Резьбозажимное stabil +Резьбозажимное соединение stabil 20x2,9xG3/4 ;Резьбозажимное stabil +Фиксатор поворота трубы 16/17/90°, без колец (оцинк. сталь);Фиксатор поворота отопление +Фиксатор поворота трубы 20/90°, без колец (оцинк. сталь);Фиксатор поворота отопление +Фиксатор поворота трубы 25/90°, без колец (оцинк. сталь);Фиксатор поворота отопление +Фиксатор поворота трубы 32/90°, с кольцами (оцинк. сталь);Фиксатор поворота отопление